From abd86777da6a5f72345bd9b5b94fc32f608fb313 Mon Sep 17 00:00:00 2001 From: Zaki Manian Date: Sun, 25 Apr 2021 22:18:52 -0700 Subject: [PATCH 01/30] Add a msg for create PeriodicVestingAccount Basic test of sending periodic vesting messages Add cli command for Periodic Vesting tx --- docs/core/proto-docs.md | 144 +++++----- proto/cosmos/vesting/v1beta1/tx.proto | 15 +- x/auth/vesting/client/cli/tx.go | 81 ++++++ x/auth/vesting/handler_test.go | 46 ++++ x/auth/vesting/msg_server.go | 47 ++++ x/auth/vesting/types/msgs.go | 57 ++++ x/auth/vesting/types/tx.pb.go | 379 ++++++++++++++++++++++++-- x/slashing/types/slashing.pb.go | 15 +- 8 files changed, 685 insertions(+), 99 deletions(-) diff --git a/docs/core/proto-docs.md b/docs/core/proto-docs.md index 92887dc08130..626d13bf6f06 100644 --- a/docs/core/proto-docs.md +++ b/docs/core/proto-docs.md @@ -569,12 +569,6 @@ - [Query](#cosmos.upgrade.v1beta1.Query) -- [cosmos/vesting/v1beta1/tx.proto](#cosmos/vesting/v1beta1/tx.proto) - - [MsgCreateVestingAccount](#cosmos.vesting.v1beta1.MsgCreateVestingAccount) - - [MsgCreateVestingAccountResponse](#cosmos.vesting.v1beta1.MsgCreateVestingAccountResponse) - - - [Msg](#cosmos.vesting.v1beta1.Msg) - - [cosmos/vesting/v1beta1/vesting.proto](#cosmos/vesting/v1beta1/vesting.proto) - [BaseVestingAccount](#cosmos.vesting.v1beta1.BaseVestingAccount) - [ContinuousVestingAccount](#cosmos.vesting.v1beta1.ContinuousVestingAccount) @@ -583,6 +577,13 @@ - [PeriodicVestingAccount](#cosmos.vesting.v1beta1.PeriodicVestingAccount) - [PermanentLockedAccount](#cosmos.vesting.v1beta1.PermanentLockedAccount) +- [cosmos/vesting/v1beta1/tx.proto](#cosmos/vesting/v1beta1/tx.proto) + - [MsgCreatePeriodicVestingAccount](#cosmos.vesting.v1beta1.MsgCreatePeriodicVestingAccount) + - [MsgCreateVestingAccount](#cosmos.vesting.v1beta1.MsgCreateVestingAccount) + - [MsgCreateVestingAccountResponse](#cosmos.vesting.v1beta1.MsgCreateVestingAccountResponse) + + - [Msg](#cosmos.vesting.v1beta1.Msg) + - [Scalar Value Types](#scalar-value-types) @@ -8043,62 +8044,6 @@ Query defines the gRPC upgrade querier service. - -

Top

- -## cosmos/vesting/v1beta1/tx.proto - - - - - -### MsgCreateVestingAccount -MsgCreateVestingAccount defines a message that enables creating a vesting -account. - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| `from_address` | [string](#string) | | | -| `to_address` | [string](#string) | | | -| `amount` | [cosmos.base.v1beta1.Coin](#cosmos.base.v1beta1.Coin) | repeated | | -| `end_time` | [int64](#int64) | | | -| `delayed` | [bool](#bool) | | | - - - - - - - - -### MsgCreateVestingAccountResponse -MsgCreateVestingAccountResponse defines the Msg/CreateVestingAccount response type. - - - - - - - - - - - - - - -### Msg -Msg defines the bank Msg service. - -| Method Name | Request Type | Response Type | Description | HTTP Verb | Endpoint | -| ----------- | ------------ | ------------- | ------------| ------- | -------- | -| `CreateVestingAccount` | [MsgCreateVestingAccount](#cosmos.vesting.v1beta1.MsgCreateVestingAccount) | [MsgCreateVestingAccountResponse](#cosmos.vesting.v1beta1.MsgCreateVestingAccountResponse) | CreateVestingAccount defines a method that enables creating a vesting account. | | - - - - -

Top

@@ -8220,6 +8165,81 @@ still be used for delegating and for governance votes even while locked. + +

Top

+ +## cosmos/vesting/v1beta1/tx.proto + + + + + +### MsgCreatePeriodicVestingAccount +MsgCreateVestingAccount defines a message that enables creating a vesting +account. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| `from_address` | [string](#string) | | | +| `to_address` | [string](#string) | | | +| `vesting_periods` | [Period](#cosmos.vesting.v1beta1.Period) | repeated | | + + + + + + + + +### MsgCreateVestingAccount +MsgCreateVestingAccount defines a message that enables creating a vesting +account. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| `from_address` | [string](#string) | | | +| `to_address` | [string](#string) | | | +| `amount` | [cosmos.base.v1beta1.Coin](#cosmos.base.v1beta1.Coin) | repeated | | +| `end_time` | [int64](#int64) | | | +| `delayed` | [bool](#bool) | | | + + + + + + + + +### MsgCreateVestingAccountResponse +MsgCreateVestingAccountResponse defines the Msg/CreateVestingAccount response type. + + + + + + + + + + + + + + +### Msg +Msg defines the bank Msg service. + +| Method Name | Request Type | Response Type | Description | HTTP Verb | Endpoint | +| ----------- | ------------ | ------------- | ------------| ------- | -------- | +| `CreateVestingAccount` | [MsgCreateVestingAccount](#cosmos.vesting.v1beta1.MsgCreateVestingAccount) | [MsgCreateVestingAccountResponse](#cosmos.vesting.v1beta1.MsgCreateVestingAccountResponse) | CreateVestingAccount defines a method that enables creating a vesting account. | | +| `CreatePeriodicVestingAccount` | [MsgCreatePeriodicVestingAccount](#cosmos.vesting.v1beta1.MsgCreatePeriodicVestingAccount) | [MsgCreateVestingAccountResponse](#cosmos.vesting.v1beta1.MsgCreateVestingAccountResponse) | | | + + + + + ## Scalar Value Types | .proto Type | Notes | C++ | Java | Python | Go | C# | PHP | Ruby | diff --git a/proto/cosmos/vesting/v1beta1/tx.proto b/proto/cosmos/vesting/v1beta1/tx.proto index c49be802a76e..e55ccfbce1b4 100644 --- a/proto/cosmos/vesting/v1beta1/tx.proto +++ b/proto/cosmos/vesting/v1beta1/tx.proto @@ -3,6 +3,7 @@ package cosmos.vesting.v1beta1; import "gogoproto/gogo.proto"; import "cosmos/base/v1beta1/coin.proto"; +import "cosmos/vesting/v1beta1/vesting.proto"; option go_package = "github.com/cosmos/cosmos-sdk/x/auth/vesting/types"; @@ -11,6 +12,7 @@ service Msg { // CreateVestingAccount defines a method that enables creating a vesting // account. rpc CreateVestingAccount(MsgCreateVestingAccount) returns (MsgCreateVestingAccountResponse); + rpc CreatePeriodicVestingAccount(MsgCreatePeriodicVestingAccount) returns (MsgCreateVestingAccountResponse); } // MsgCreateVestingAccount defines a message that enables creating a vesting @@ -28,4 +30,15 @@ message MsgCreateVestingAccount { } // MsgCreateVestingAccountResponse defines the Msg/CreateVestingAccount response type. -message MsgCreateVestingAccountResponse {} \ No newline at end of file +message MsgCreateVestingAccountResponse {} + + +// MsgCreateVestingAccount defines a message that enables creating a vesting +// account. +message MsgCreatePeriodicVestingAccount { + option (gogoproto.equal) = false; + + string from_address = 1 [(gogoproto.moretags) = "yaml:\"from_address\""]; + string to_address = 2 [(gogoproto.moretags) = "yaml:\"to_address\""]; + repeated Period vesting_periods = 3 [(gogoproto.nullable) = false]; +} \ No newline at end of file diff --git a/x/auth/vesting/client/cli/tx.go b/x/auth/vesting/client/cli/tx.go index c6c2ac1432d2..5663448d14c0 100644 --- a/x/auth/vesting/client/cli/tx.go +++ b/x/auth/vesting/client/cli/tx.go @@ -1,6 +1,8 @@ package cli import ( + "encoding/json" + "io/ioutil" "strconv" "github.com/spf13/cobra" @@ -30,6 +32,7 @@ func GetTxCmd() *cobra.Command { txCmd.AddCommand( NewMsgCreateVestingAccountCmd(), + NewMsgCreatePeriodicVestingAccountCmd(), ) return txCmd @@ -86,3 +89,81 @@ timestamp.`, return cmd } + +type InputPeriod struct { + Coins string `json:"coins"` + Time int64 `json:"unix_time"` +} + +// NewMsgCreateVestingAccountCmd returns a CLI command handler for creating a +// MsgCreateVestingAccount transaction. +func NewMsgCreatePeriodicVestingAccountCmd() *cobra.Command { + cmd := &cobra.Command{ + Use: "create-periodic-vesting-account [to_address] [periods_json_file]", + Short: "Create a new vesting account funded with an allocation of tokens.", + Long: `Create a new vesting account funded with an allocation of tokens. This takes a destingation address and + a period json file. + Where periods.json contains: + + An array of coin strings and unix epoch times for coins to vest + +[ +{ + "coins": "10test", + "unix_time":1620016673 + }, + { + "coins": "10test", + "unix_time":1620026673 + }, +] + `, + Args: cobra.ExactArgs(3), + RunE: func(cmd *cobra.Command, args []string) error { + clientCtx, err := client.GetClientTxContext(cmd) + if err != nil { + return err + } + toAddr, err := sdk.AccAddressFromBech32(args[0]) + if err != nil { + return err + } + + contents, err := ioutil.ReadFile(args[1]) + if err != nil { + return err + } + + var inputPeriods []InputPeriod + + err = json.Unmarshal(contents, inputPeriods) + if err != nil { + return err + } + + var periods []types.Period + + for _, p := range inputPeriods { + + amount, err := sdk.ParseCoinsNormalized(p.Coins) + if err != nil { + return err + } + period := types.Period{Length: p.Time, Amount: amount} + periods = append(periods, period) + } + + msg := types.NewMsgCreatePeriodicVestingAccount(clientCtx.GetFromAddress(), toAddr, periods) + if err := msg.ValidateBasic(); err != nil { + return err + } + + return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msg) + }, + } + + cmd.Flags().Bool(FlagDelayed, false, "Create a delayed vesting account if true") + flags.AddTxFlagsToCmd(cmd) + + return cmd +} diff --git a/x/auth/vesting/handler_test.go b/x/auth/vesting/handler_test.go index 48be156b83a8..68dd6d846dee 100644 --- a/x/auth/vesting/handler_test.go +++ b/x/auth/vesting/handler_test.go @@ -91,6 +91,52 @@ func (suite *HandlerTestSuite) TestMsgCreateVestingAccount() { } } +func (suite *HandlerTestSuite) TestMsgCreatePeriodicVestingAccount() { + ctx := suite.app.BaseApp.NewContext(false, tmproto.Header{Height: suite.app.LastBlockHeight() + 1}) + + balances := sdk.NewCoins(sdk.NewInt64Coin("test", 1000)) + addr1 := sdk.AccAddress([]byte("addr1_______________")) + addr3 := sdk.AccAddress([]byte("addr3_______________")) + + acc1 := suite.app.AccountKeeper.NewAccountWithAddress(ctx, addr1) + + period := []types.Period{{Length: 5000, Amount: balances}} + suite.app.AccountKeeper.SetAccount(ctx, acc1) + suite.Require().NoError(suite.app.BankKeeper.SetBalances(ctx, addr1, balances)) + + testCases := []struct { + name string + msg *types.MsgCreatePeriodicVestingAccount + expectErr bool + }{ + { + name: "continuous vesting account already exists", + msg: types.NewMsgCreatePeriodicVestingAccount(addr1, addr3, period), + expectErr: true, + }, + } + + for _, tc := range testCases { + tc := tc + + suite.Run(tc.name, func() { + res, err := suite.handler(ctx, tc.msg) + if tc.expectErr { + suite.Require().Error(err) + } else { + suite.Require().NoError(err) + suite.Require().NotNil(res) + + toAddr, err := sdk.AccAddressFromBech32(tc.msg.ToAddress) + suite.Require().NoError(err) + accI := suite.app.AccountKeeper.GetAccount(ctx, toAddr) + suite.Require().NotNil(accI) + + } + }) + } +} + func TestHandlerTestSuite(t *testing.T) { suite.Run(t, new(HandlerTestSuite)) } diff --git a/x/auth/vesting/msg_server.go b/x/auth/vesting/msg_server.go index dadd65dbcf1c..8b95213f4b48 100644 --- a/x/auth/vesting/msg_server.go +++ b/x/auth/vesting/msg_server.go @@ -98,3 +98,50 @@ func (s msgServer) CreateVestingAccount(goCtx context.Context, msg *types.MsgCre return &types.MsgCreateVestingAccountResponse{}, nil } + +func (s msgServer) CreatePeriodicVestingAccount(goCtx context.Context, msg *types.MsgCreatePeriodicVestingAccount) (*types.MsgCreateVestingAccountResponse, error) { + ctx := sdk.UnwrapSDKContext(goCtx) + + ak := s.AccountKeeper + bk := s.BankKeeper + + from, err := sdk.AccAddressFromBech32(msg.FromAddress) + if err != nil { + return nil, err + } + to, err := sdk.AccAddressFromBech32(msg.ToAddress) + if err != nil { + return nil, err + } + + if bk.BlockedAddr(to) { + return nil, sdkerrors.Wrapf(sdkerrors.ErrUnauthorized, "%s is not allowed to receive funds", msg.ToAddress) + } + + if acc := ak.GetAccount(ctx, to); acc != nil { + return nil, sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "account %s already exists", msg.ToAddress) + } + var totalCoins sdk.Coins + + for _, period := range msg.VestingPeriods { + totalCoins.Add(period.Amount...) + } + + baseAccount := ak.NewAccountWithAddress(ctx, to) + + types.NewPeriodicVestingAccount(baseAccount.(*authtypes.BaseAccount), totalCoins.Sort(), ctx.BlockTime().Unix(), msg.VestingPeriods) + + err = bk.SendCoins(ctx, from, to, totalCoins) + if err != nil { + return nil, err + } + + ctx.EventManager().EmitEvent( + sdk.NewEvent( + sdk.EventTypeMessage, + sdk.NewAttribute(sdk.AttributeKeyModule, types.AttributeValueCategory), + ), + ) + return &types.MsgCreateVestingAccountResponse{}, nil + +} diff --git a/x/auth/vesting/types/msgs.go b/x/auth/vesting/types/msgs.go index 3308e0304881..a56e9c95f13f 100644 --- a/x/auth/vesting/types/msgs.go +++ b/x/auth/vesting/types/msgs.go @@ -8,8 +8,13 @@ import ( // TypeMsgCreateVestingAccount defines the type value for a MsgCreateVestingAccount. const TypeMsgCreateVestingAccount = "msg_create_vesting_account" +// TypeMsgCreatePeriodicVestingAccount defines the type value for a MsgCreateVestingAccount. +const TypeMsgCreatePeriodicVestingAccount = "msg_create_periodic_vesting_account" + var _ sdk.Msg = &MsgCreateVestingAccount{} +var _ sdk.Msg = &MsgCreatePeriodicVestingAccount{} + // NewMsgCreateVestingAccount returns a reference to a new MsgCreateVestingAccount. //nolint:interfacer func NewMsgCreateVestingAccount(fromAddr, toAddr sdk.AccAddress, amount sdk.Coins, endTime int64, delayed bool) *MsgCreateVestingAccount { @@ -75,3 +80,55 @@ func (msg MsgCreateVestingAccount) GetSigners() []sdk.AccAddress { } return []sdk.AccAddress{from} } + +// NewMsgCreateVestingAccount returns a reference to a new MsgCreateVestingAccount. +//nolint:interfacer +func NewMsgCreatePeriodicVestingAccount(fromAddr, toAddr sdk.AccAddress, periods []Period) *MsgCreatePeriodicVestingAccount { + return &MsgCreatePeriodicVestingAccount{ + FromAddress: fromAddr.String(), + ToAddress: toAddr.String(), + VestingPeriods: periods, + } +} + +// Route returns the message route for a MsgCreateVestingAccount. +func (msg MsgCreatePeriodicVestingAccount) Route() string { return RouterKey } + +// Type returns the message type for a MsgCreateVestingAccount. +func (msg MsgCreatePeriodicVestingAccount) Type() string { return TypeMsgCreatePeriodicVestingAccount } + +// GetSigners returns the expected signers for a MsgCreateVestingAccount. +func (msg MsgCreatePeriodicVestingAccount) GetSigners() []sdk.AccAddress { + from, err := sdk.AccAddressFromBech32(msg.FromAddress) + if err != nil { + panic(err) + } + return []sdk.AccAddress{from} +} + +// GetSignBytes returns the bytes all expected signers must sign over for a +// MsgCreateVestingAccount. +func (msg MsgCreatePeriodicVestingAccount) GetSignBytes() []byte { + return sdk.MustSortJSON(amino.MustMarshalJSON(&msg)) +} + +// ValidateBasic Implements Msg. +func (msg MsgCreatePeriodicVestingAccount) ValidateBasic() error { + from, err := sdk.AccAddressFromBech32(msg.FromAddress) + if err != nil { + return err + } + to, err := sdk.AccAddressFromBech32(msg.ToAddress) + if err != nil { + return err + } + if err := sdk.VerifyAddressFormat(from); err != nil { + return sdkerrors.Wrapf(sdkerrors.ErrInvalidAddress, "invalid sender address: %s", err) + } + + if err := sdk.VerifyAddressFormat(to); err != nil { + return sdkerrors.Wrapf(sdkerrors.ErrInvalidAddress, "invalid recipient address: %s", err) + } + + return nil +} diff --git a/x/auth/vesting/types/tx.pb.go b/x/auth/vesting/types/tx.pb.go index d07a154dd326..41719ce8e6d3 100644 --- a/x/auth/vesting/types/tx.pb.go +++ b/x/auth/vesting/types/tx.pb.go @@ -145,41 +145,108 @@ func (m *MsgCreateVestingAccountResponse) XXX_DiscardUnknown() { var xxx_messageInfo_MsgCreateVestingAccountResponse proto.InternalMessageInfo +// MsgCreateVestingAccount defines a message that enables creating a vesting +// account. +type MsgCreatePeriodicVestingAccount struct { + FromAddress string `protobuf:"bytes,1,opt,name=from_address,json=fromAddress,proto3" json:"from_address,omitempty" yaml:"from_address"` + ToAddress string `protobuf:"bytes,2,opt,name=to_address,json=toAddress,proto3" json:"to_address,omitempty" yaml:"to_address"` + VestingPeriods []Period `protobuf:"bytes,3,rep,name=vesting_periods,json=vestingPeriods,proto3" json:"vesting_periods"` +} + +func (m *MsgCreatePeriodicVestingAccount) Reset() { *m = MsgCreatePeriodicVestingAccount{} } +func (m *MsgCreatePeriodicVestingAccount) String() string { return proto.CompactTextString(m) } +func (*MsgCreatePeriodicVestingAccount) ProtoMessage() {} +func (*MsgCreatePeriodicVestingAccount) Descriptor() ([]byte, []int) { + return fileDescriptor_5338ca97811f9792, []int{2} +} +func (m *MsgCreatePeriodicVestingAccount) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MsgCreatePeriodicVestingAccount) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MsgCreatePeriodicVestingAccount.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 *MsgCreatePeriodicVestingAccount) XXX_Merge(src proto.Message) { + xxx_messageInfo_MsgCreatePeriodicVestingAccount.Merge(m, src) +} +func (m *MsgCreatePeriodicVestingAccount) XXX_Size() int { + return m.Size() +} +func (m *MsgCreatePeriodicVestingAccount) XXX_DiscardUnknown() { + xxx_messageInfo_MsgCreatePeriodicVestingAccount.DiscardUnknown(m) +} + +var xxx_messageInfo_MsgCreatePeriodicVestingAccount proto.InternalMessageInfo + +func (m *MsgCreatePeriodicVestingAccount) GetFromAddress() string { + if m != nil { + return m.FromAddress + } + return "" +} + +func (m *MsgCreatePeriodicVestingAccount) GetToAddress() string { + if m != nil { + return m.ToAddress + } + return "" +} + +func (m *MsgCreatePeriodicVestingAccount) GetVestingPeriods() []Period { + if m != nil { + return m.VestingPeriods + } + return nil +} + func init() { proto.RegisterType((*MsgCreateVestingAccount)(nil), "cosmos.vesting.v1beta1.MsgCreateVestingAccount") proto.RegisterType((*MsgCreateVestingAccountResponse)(nil), "cosmos.vesting.v1beta1.MsgCreateVestingAccountResponse") + proto.RegisterType((*MsgCreatePeriodicVestingAccount)(nil), "cosmos.vesting.v1beta1.MsgCreatePeriodicVestingAccount") } func init() { proto.RegisterFile("cosmos/vesting/v1beta1/tx.proto", fileDescriptor_5338ca97811f9792) } var fileDescriptor_5338ca97811f9792 = []byte{ - // 410 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x52, 0xbd, 0xae, 0xd3, 0x30, - 0x14, 0x8e, 0x6f, 0x2e, 0xf7, 0xc7, 0x17, 0x09, 0x91, 0x16, 0x1a, 0x3a, 0xc4, 0x21, 0x53, 0x16, - 0x6c, 0x5a, 0x90, 0x90, 0xba, 0x35, 0x1d, 0x51, 0x97, 0x08, 0x31, 0xb0, 0x54, 0x4e, 0x62, 0xd2, - 0x88, 0x26, 0xae, 0x62, 0xb7, 0x6a, 0x37, 0x46, 0x46, 0x1e, 0x81, 0x99, 0xa7, 0x60, 0xec, 0xd8, - 0x91, 0x29, 0xa0, 0x76, 0x61, 0xee, 0x13, 0xa0, 0xc4, 0x49, 0x61, 0x68, 0x91, 0x98, 0xec, 0xa3, - 0xef, 0xc7, 0xe7, 0x7c, 0x3e, 0x10, 0x85, 0x5c, 0xa4, 0x5c, 0x90, 0x25, 0x13, 0x32, 0xc9, 0x62, - 0xb2, 0xec, 0x05, 0x4c, 0xd2, 0x1e, 0x91, 0x2b, 0x3c, 0xcf, 0xb9, 0xe4, 0xc6, 0x63, 0x45, 0xc0, - 0x35, 0x01, 0xd7, 0x84, 0x6e, 0x3b, 0xe6, 0x31, 0xaf, 0x28, 0xa4, 0xbc, 0x29, 0x76, 0xd7, 0xaa, - 0xed, 0x02, 0x2a, 0xd8, 0xd1, 0x2b, 0xe4, 0x49, 0xa6, 0x70, 0xe7, 0xdb, 0x05, 0xec, 0x8c, 0x45, - 0x3c, 0xca, 0x19, 0x95, 0xec, 0xad, 0xb2, 0x1c, 0x86, 0x21, 0x5f, 0x64, 0xd2, 0x18, 0xc0, 0xfb, - 0xef, 0x73, 0x9e, 0x4e, 0x68, 0x14, 0xe5, 0x4c, 0x08, 0x13, 0xd8, 0xc0, 0xbd, 0xf5, 0x3a, 0x87, - 0x02, 0xb5, 0xd6, 0x34, 0x9d, 0x0d, 0x9c, 0xbf, 0x51, 0xc7, 0xbf, 0x2b, 0xcb, 0xa1, 0xaa, 0x8c, - 0x97, 0x10, 0x4a, 0x7e, 0x54, 0x5e, 0x54, 0xca, 0x47, 0x87, 0x02, 0x3d, 0x54, 0xca, 0x3f, 0x98, - 0xe3, 0xdf, 0x4a, 0xde, 0xa8, 0x42, 0x78, 0x45, 0xd3, 0xf2, 0x6d, 0x53, 0xb7, 0x75, 0xf7, 0xae, - 0xff, 0x04, 0xd7, 0xc3, 0x96, 0xed, 0x37, 0x93, 0xe2, 0x11, 0x4f, 0x32, 0xef, 0xf9, 0xa6, 0x40, - 0xda, 0xd7, 0x1f, 0xc8, 0x8d, 0x13, 0x39, 0x5d, 0x04, 0x38, 0xe4, 0x29, 0xa9, 0x67, 0x55, 0xc7, - 0x33, 0x11, 0x7d, 0x20, 0x72, 0x3d, 0x67, 0xa2, 0x12, 0x08, 0xbf, 0xb6, 0x36, 0x30, 0xbc, 0x61, - 0x59, 0x34, 0x91, 0x49, 0xca, 0xcc, 0x4b, 0x1b, 0xb8, 0xba, 0xd7, 0x3a, 0x14, 0xe8, 0x81, 0x6a, - 0xac, 0x41, 0x1c, 0xff, 0x9a, 0x65, 0xd1, 0x9b, 0x24, 0x65, 0x86, 0x09, 0xaf, 0x23, 0x36, 0xa3, - 0x6b, 0x16, 0x99, 0xf7, 0x6c, 0xe0, 0xde, 0xf8, 0x4d, 0x39, 0xb8, 0xfc, 0xf5, 0x05, 0x01, 0xe7, - 0x29, 0x44, 0x67, 0x12, 0xf4, 0x99, 0x98, 0xf3, 0x4c, 0xb0, 0xfe, 0x27, 0x00, 0xf5, 0xb1, 0x88, - 0x8d, 0x8f, 0x00, 0xb6, 0x4f, 0x46, 0x4d, 0xf0, 0xe9, 0x5f, 0xc5, 0x67, 0x9c, 0xbb, 0xaf, 0xfe, - 0x53, 0xd0, 0xb4, 0xe2, 0xbd, 0xde, 0xec, 0x2c, 0xb0, 0xdd, 0x59, 0xe0, 0xe7, 0xce, 0x02, 0x9f, - 0xf7, 0x96, 0xb6, 0xdd, 0x5b, 0xda, 0xf7, 0xbd, 0xa5, 0xbd, 0xeb, 0xfd, 0x33, 0xc9, 0x15, 0xa1, - 0x0b, 0x39, 0x3d, 0xae, 0x65, 0x15, 0x6c, 0x70, 0x55, 0x2d, 0xd1, 0x8b, 0xdf, 0x01, 0x00, 0x00, - 0xff, 0xff, 0xe7, 0x28, 0xaf, 0xe5, 0xb5, 0x02, 0x00, 0x00, + // 479 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xc4, 0x53, 0x3d, 0x6f, 0xd3, 0x40, + 0x18, 0xf6, 0x25, 0xa1, 0x1f, 0x57, 0x44, 0x85, 0x5b, 0xa8, 0x89, 0x90, 0x1d, 0x2c, 0x06, 0x2f, + 0x9c, 0x49, 0x41, 0x42, 0xca, 0x56, 0x77, 0x44, 0x91, 0x90, 0x85, 0x18, 0x58, 0x22, 0xc7, 0xf7, + 0xe2, 0x9e, 0xa8, 0x7d, 0x91, 0xef, 0x52, 0x35, 0x1b, 0x3f, 0xa1, 0x3b, 0x0b, 0x33, 0xbf, 0x82, + 0xb1, 0x63, 0x47, 0xa6, 0x80, 0x92, 0xa5, 0x73, 0x7e, 0x01, 0xf2, 0xdd, 0x39, 0x74, 0x48, 0x8a, + 0x60, 0x61, 0x4a, 0x5e, 0x3f, 0x1f, 0xf7, 0xde, 0xa3, 0xe7, 0xb0, 0x97, 0x72, 0x91, 0x73, 0x11, + 0x9e, 0x81, 0x90, 0xac, 0xc8, 0xc2, 0xb3, 0xee, 0x10, 0x64, 0xd2, 0x0d, 0xe5, 0x39, 0x19, 0x95, + 0x5c, 0x72, 0xfb, 0xa1, 0x26, 0x10, 0x43, 0x20, 0x86, 0xd0, 0xde, 0xcf, 0x78, 0xc6, 0x15, 0x25, + 0xac, 0xfe, 0x69, 0x76, 0xdb, 0x35, 0x76, 0xc3, 0x44, 0xc0, 0xd2, 0x2b, 0xe5, 0xac, 0x30, 0xf8, + 0xd3, 0x35, 0xc7, 0xd5, 0xee, 0x8a, 0xe5, 0x7f, 0x6b, 0xe0, 0x83, 0xbe, 0xc8, 0x8e, 0x4b, 0x48, + 0x24, 0xbc, 0xd3, 0xd0, 0x51, 0x9a, 0xf2, 0x71, 0x21, 0xed, 0x1e, 0xbe, 0xfb, 0xa1, 0xe4, 0xf9, + 0x20, 0xa1, 0xb4, 0x04, 0x21, 0x1c, 0xd4, 0x41, 0xc1, 0x76, 0x74, 0xb0, 0x98, 0x7a, 0x7b, 0x93, + 0x24, 0x3f, 0xed, 0xf9, 0x37, 0x51, 0x3f, 0xde, 0xa9, 0xc6, 0x23, 0x3d, 0xd9, 0x2f, 0x31, 0x96, + 0x7c, 0xa9, 0x6c, 0x28, 0xe5, 0x83, 0xc5, 0xd4, 0xbb, 0xaf, 0x95, 0xbf, 0x31, 0x3f, 0xde, 0x96, + 0xbc, 0x56, 0xa5, 0x78, 0x23, 0xc9, 0xab, 0xb3, 0x9d, 0x66, 0xa7, 0x19, 0xec, 0x1c, 0x3e, 0x22, + 0x26, 0x92, 0xea, 0x92, 0x75, 0x1e, 0xe4, 0x98, 0xb3, 0x22, 0x7a, 0x7e, 0x39, 0xf5, 0xac, 0xaf, + 0x3f, 0xbc, 0x20, 0x63, 0xf2, 0x64, 0x3c, 0x24, 0x29, 0xcf, 0x43, 0x73, 0x63, 0xfd, 0xf3, 0x4c, + 0xd0, 0x8f, 0xa1, 0x9c, 0x8c, 0x40, 0x28, 0x81, 0x88, 0x8d, 0xb5, 0x4d, 0xf0, 0x16, 0x14, 0x74, + 0x20, 0x59, 0x0e, 0x4e, 0xab, 0x83, 0x82, 0x66, 0xb4, 0xb7, 0x98, 0x7a, 0xbb, 0x7a, 0xb1, 0x1a, + 0xf1, 0xe3, 0x4d, 0x28, 0xe8, 0x5b, 0x96, 0x83, 0xed, 0xe0, 0x4d, 0x0a, 0xa7, 0xc9, 0x04, 0xa8, + 0x73, 0xa7, 0x83, 0x82, 0xad, 0xb8, 0x1e, 0x7b, 0xad, 0xeb, 0x2f, 0x1e, 0xf2, 0x9f, 0x60, 0x6f, + 0x4d, 0x82, 0x31, 0x88, 0x11, 0x2f, 0x04, 0xf8, 0xd7, 0xe8, 0x06, 0xe7, 0x0d, 0x94, 0x8c, 0x53, + 0x96, 0xfe, 0xf7, 0xb4, 0xfb, 0x78, 0xd7, 0x94, 0x61, 0x30, 0x52, 0x3b, 0x09, 0x13, 0xbb, 0x4b, + 0x56, 0x37, 0x91, 0xe8, 0xd5, 0xa3, 0x56, 0x95, 0x7d, 0x7c, 0xcf, 0xa0, 0xfa, 0xa3, 0x50, 0x69, + 0x58, 0x87, 0x9f, 0x1b, 0xb8, 0xd9, 0x17, 0x99, 0xfd, 0x09, 0xe1, 0xfd, 0x95, 0xad, 0x0a, 0xd7, + 0x99, 0xaf, 0x09, 0xb1, 0xfd, 0xea, 0x2f, 0x05, 0x75, 0xea, 0xf6, 0x05, 0xc2, 0x8f, 0x6f, 0x8d, + 0xfc, 0xcf, 0xce, 0xab, 0x85, 0xff, 0xbc, 0x52, 0xf4, 0xfa, 0x72, 0xe6, 0xa2, 0xab, 0x99, 0x8b, + 0x7e, 0xce, 0x5c, 0x74, 0x31, 0x77, 0xad, 0xab, 0xb9, 0x6b, 0x7d, 0x9f, 0xbb, 0xd6, 0xfb, 0xee, + 0xad, 0x3d, 0x3e, 0x0f, 0x93, 0xb1, 0x3c, 0x59, 0xbe, 0x65, 0x55, 0xeb, 0xe1, 0x86, 0x7a, 0xc2, + 0x2f, 0x7e, 0x05, 0x00, 0x00, 0xff, 0xff, 0xaa, 0x8b, 0x7b, 0x18, 0x59, 0x04, 0x00, 0x00, } func (this *MsgCreateVestingAccount) Equal(that interface{}) bool { @@ -239,6 +306,7 @@ type MsgClient interface { // CreateVestingAccount defines a method that enables creating a vesting // account. CreateVestingAccount(ctx context.Context, in *MsgCreateVestingAccount, opts ...grpc.CallOption) (*MsgCreateVestingAccountResponse, error) + CreatePeriodicVestingAccount(ctx context.Context, in *MsgCreatePeriodicVestingAccount, opts ...grpc.CallOption) (*MsgCreateVestingAccountResponse, error) } type msgClient struct { @@ -258,11 +326,21 @@ func (c *msgClient) CreateVestingAccount(ctx context.Context, in *MsgCreateVesti return out, nil } +func (c *msgClient) CreatePeriodicVestingAccount(ctx context.Context, in *MsgCreatePeriodicVestingAccount, opts ...grpc.CallOption) (*MsgCreateVestingAccountResponse, error) { + out := new(MsgCreateVestingAccountResponse) + err := c.cc.Invoke(ctx, "/cosmos.vesting.v1beta1.Msg/CreatePeriodicVestingAccount", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + // MsgServer is the server API for Msg service. type MsgServer interface { // CreateVestingAccount defines a method that enables creating a vesting // account. CreateVestingAccount(context.Context, *MsgCreateVestingAccount) (*MsgCreateVestingAccountResponse, error) + CreatePeriodicVestingAccount(context.Context, *MsgCreatePeriodicVestingAccount) (*MsgCreateVestingAccountResponse, error) } // UnimplementedMsgServer can be embedded to have forward compatible implementations. @@ -272,6 +350,9 @@ type UnimplementedMsgServer struct { func (*UnimplementedMsgServer) CreateVestingAccount(ctx context.Context, req *MsgCreateVestingAccount) (*MsgCreateVestingAccountResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method CreateVestingAccount not implemented") } +func (*UnimplementedMsgServer) CreatePeriodicVestingAccount(ctx context.Context, req *MsgCreatePeriodicVestingAccount) (*MsgCreateVestingAccountResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method CreatePeriodicVestingAccount not implemented") +} func RegisterMsgServer(s grpc1.Server, srv MsgServer) { s.RegisterService(&_Msg_serviceDesc, srv) @@ -295,6 +376,24 @@ func _Msg_CreateVestingAccount_Handler(srv interface{}, ctx context.Context, dec return interceptor(ctx, in, info, handler) } +func _Msg_CreatePeriodicVestingAccount_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(MsgCreatePeriodicVestingAccount) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(MsgServer).CreatePeriodicVestingAccount(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/cosmos.vesting.v1beta1.Msg/CreatePeriodicVestingAccount", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(MsgServer).CreatePeriodicVestingAccount(ctx, req.(*MsgCreatePeriodicVestingAccount)) + } + return interceptor(ctx, in, info, handler) +} + var _Msg_serviceDesc = grpc.ServiceDesc{ ServiceName: "cosmos.vesting.v1beta1.Msg", HandlerType: (*MsgServer)(nil), @@ -303,6 +402,10 @@ var _Msg_serviceDesc = grpc.ServiceDesc{ MethodName: "CreateVestingAccount", Handler: _Msg_CreateVestingAccount_Handler, }, + { + MethodName: "CreatePeriodicVestingAccount", + Handler: _Msg_CreatePeriodicVestingAccount_Handler, + }, }, Streams: []grpc.StreamDesc{}, Metadata: "cosmos/vesting/v1beta1/tx.proto", @@ -397,6 +500,57 @@ func (m *MsgCreateVestingAccountResponse) MarshalToSizedBuffer(dAtA []byte) (int return len(dAtA) - i, nil } +func (m *MsgCreatePeriodicVestingAccount) 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 *MsgCreatePeriodicVestingAccount) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MsgCreatePeriodicVestingAccount) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.VestingPeriods) > 0 { + for iNdEx := len(m.VestingPeriods) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.VestingPeriods[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintTx(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x1a + } + } + if len(m.ToAddress) > 0 { + i -= len(m.ToAddress) + copy(dAtA[i:], m.ToAddress) + i = encodeVarintTx(dAtA, i, uint64(len(m.ToAddress))) + i-- + dAtA[i] = 0x12 + } + if len(m.FromAddress) > 0 { + i -= len(m.FromAddress) + copy(dAtA[i:], m.FromAddress) + i = encodeVarintTx(dAtA, i, uint64(len(m.FromAddress))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + func encodeVarintTx(dAtA []byte, offset int, v uint64) int { offset -= sovTx(v) base := offset @@ -446,6 +600,29 @@ func (m *MsgCreateVestingAccountResponse) Size() (n int) { return n } +func (m *MsgCreatePeriodicVestingAccount) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.FromAddress) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + l = len(m.ToAddress) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + if len(m.VestingPeriods) > 0 { + for _, e := range m.VestingPeriods { + l = e.Size() + n += 1 + l + sovTx(uint64(l)) + } + } + return n +} + func sovTx(x uint64) (n int) { return (math_bits.Len64(x|1) + 6) / 7 } @@ -689,6 +866,154 @@ func (m *MsgCreateVestingAccountResponse) Unmarshal(dAtA []byte) error { } return nil } +func (m *MsgCreatePeriodicVestingAccount) 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 ErrIntOverflowTx + } + 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: MsgCreatePeriodicVestingAccount: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MsgCreatePeriodicVestingAccount: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field FromAddress", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + 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 ErrInvalidLengthTx + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.FromAddress = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ToAddress", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + 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 ErrInvalidLengthTx + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ToAddress = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field VestingPeriods", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthTx + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.VestingPeriods = append(m.VestingPeriods, Period{}) + if err := m.VestingPeriods[len(m.VestingPeriods)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipTx(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthTx + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} func skipTx(dAtA []byte) (n int, err error) { l := len(dAtA) iNdEx := 0 diff --git a/x/slashing/types/slashing.pb.go b/x/slashing/types/slashing.pb.go index 633b4c5bb944..1db4757a95a8 100644 --- a/x/slashing/types/slashing.pb.go +++ b/x/slashing/types/slashing.pb.go @@ -33,19 +33,16 @@ const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package // liveness activity. type ValidatorSigningInfo struct { Address string `protobuf:"bytes,1,opt,name=address,proto3" json:"address,omitempty"` - // Height at which validator was first a candidate OR was unjailed + // height at which validator was first a candidate OR was unjailed StartHeight int64 `protobuf:"varint,2,opt,name=start_height,json=startHeight,proto3" json:"start_height,omitempty" yaml:"start_height"` - // Index which is incremented each time the validator was a bonded - // in a block and may have signed a precommit or not. This in conjunction with the - // `SignedBlocksWindow` param determines the index in the `MissedBlocksBitArray`. + // index offset into signed block bit array IndexOffset int64 `protobuf:"varint,3,opt,name=index_offset,json=indexOffset,proto3" json:"index_offset,omitempty" yaml:"index_offset"` - // Timestamp until which the validator is jailed due to liveness downtime. + // timestamp validator cannot be unjailed until JailedUntil time.Time `protobuf:"bytes,4,opt,name=jailed_until,json=jailedUntil,proto3,stdtime" json:"jailed_until" yaml:"jailed_until"` - // Whether or not a validator has been tombstoned (killed out of validator set). It is set - // once the validator commits an equivocation or for any other configured misbehiavor. + // whether or not a validator has been tombstoned (killed out of validator + // set) Tombstoned bool `protobuf:"varint,5,opt,name=tombstoned,proto3" json:"tombstoned,omitempty"` - // A counter kept to avoid unnecessary array reads. - // Note that `Sum(MissedBlocksBitArray)` always equals `MissedBlocksCounter`. + // missed blocks counter (to avoid scanning the array every time) MissedBlocksCounter int64 `protobuf:"varint,6,opt,name=missed_blocks_counter,json=missedBlocksCounter,proto3" json:"missed_blocks_counter,omitempty" yaml:"missed_blocks_counter"` } From 5e65a9cb1864d181cf0d81ae65f7ce20b2d75127 Mon Sep 17 00:00:00 2001 From: Zaki Manian Date: Thu, 3 Jun 2021 22:50:15 -0700 Subject: [PATCH 02/30] Address code review comments --- proto/cosmos/vesting/v1beta1/tx.proto | 2 +- x/auth/vesting/client/cli/tx.go | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/proto/cosmos/vesting/v1beta1/tx.proto b/proto/cosmos/vesting/v1beta1/tx.proto index e55ccfbce1b4..63dc50299278 100644 --- a/proto/cosmos/vesting/v1beta1/tx.proto +++ b/proto/cosmos/vesting/v1beta1/tx.proto @@ -41,4 +41,4 @@ message MsgCreatePeriodicVestingAccount { string from_address = 1 [(gogoproto.moretags) = "yaml:\"from_address\""]; string to_address = 2 [(gogoproto.moretags) = "yaml:\"to_address\""]; repeated Period vesting_periods = 3 [(gogoproto.nullable) = false]; -} \ No newline at end of file +} diff --git a/x/auth/vesting/client/cli/tx.go b/x/auth/vesting/client/cli/tx.go index 5663448d14c0..8ad77b300cb6 100644 --- a/x/auth/vesting/client/cli/tx.go +++ b/x/auth/vesting/client/cli/tx.go @@ -91,8 +91,8 @@ timestamp.`, } type InputPeriod struct { - Coins string `json:"coins"` - Time int64 `json:"unix_time"` + Coins string `json:"coins"` + Length int64 `json:"length_seconds"` } // NewMsgCreateVestingAccountCmd returns a CLI command handler for creating a @@ -101,7 +101,7 @@ func NewMsgCreatePeriodicVestingAccountCmd() *cobra.Command { cmd := &cobra.Command{ Use: "create-periodic-vesting-account [to_address] [periods_json_file]", Short: "Create a new vesting account funded with an allocation of tokens.", - Long: `Create a new vesting account funded with an allocation of tokens. This takes a destingation address and + Long: `Create a new vesting account funded with an allocation of tokens. This takes a destination address and a period json file. Where periods.json contains: @@ -110,11 +110,11 @@ func NewMsgCreatePeriodicVestingAccountCmd() *cobra.Command { [ { "coins": "10test", - "unix_time":1620016673 + "length_seconds":1620016673 }, { "coins": "10test", - "unix_time":1620026673 + "length_seconds":1620026673 }, ] `, @@ -149,7 +149,7 @@ func NewMsgCreatePeriodicVestingAccountCmd() *cobra.Command { if err != nil { return err } - period := types.Period{Length: p.Time, Amount: amount} + period := types.Period{Length: p.Length, Amount: amount} periods = append(periods, period) } From 48098c57d075a2f2f4ce9843f9b4f5aa9c1b615b Mon Sep 17 00:00:00 2001 From: Zaki Manian Date: Sun, 20 Jun 2021 21:25:30 -0700 Subject: [PATCH 03/30] validate periodic vesting messages period length is greater than 0. --- x/auth/vesting/types/msgs.go | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/x/auth/vesting/types/msgs.go b/x/auth/vesting/types/msgs.go index a56e9c95f13f..65c2e1fa13b4 100644 --- a/x/auth/vesting/types/msgs.go +++ b/x/auth/vesting/types/msgs.go @@ -1,6 +1,8 @@ package types import ( + "fmt" + sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" ) @@ -130,5 +132,11 @@ func (msg MsgCreatePeriodicVestingAccount) ValidateBasic() error { return sdkerrors.Wrapf(sdkerrors.ErrInvalidAddress, "invalid recipient address: %s", err) } + for i, period := range msg.VestingPeriods { + if period.Length < 1 { + return fmt.Errorf("invalid period length of %d in period %d. Length must be greater than 0.", period.Length, i) + } + } + return nil } From d0a7a0aa86a7ac43c0f4fa8662038323de9c5046 Mon Sep 17 00:00:00 2001 From: Zaki Manian Date: Sun, 20 Jun 2021 21:26:50 -0700 Subject: [PATCH 04/30] update error message on invalid vesting lenght --- x/auth/vesting/types/msgs.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x/auth/vesting/types/msgs.go b/x/auth/vesting/types/msgs.go index 65c2e1fa13b4..a62dee3f62c1 100644 --- a/x/auth/vesting/types/msgs.go +++ b/x/auth/vesting/types/msgs.go @@ -134,7 +134,7 @@ func (msg MsgCreatePeriodicVestingAccount) ValidateBasic() error { for i, period := range msg.VestingPeriods { if period.Length < 1 { - return fmt.Errorf("invalid period length of %d in period %d. Length must be greater than 0.", period.Length, i) + return fmt.Errorf("invalid period length of %d in period %d, length must be greater than 0", period.Length, i) } } From b4b4d8130b34a663b31c6bcfb009d662b067b5b4 Mon Sep 17 00:00:00 2001 From: Zaki Manian Date: Sun, 20 Jun 2021 21:39:22 -0700 Subject: [PATCH 05/30] error on invalid lengths in json more realistic example values --- x/auth/vesting/client/cli/tx.go | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/x/auth/vesting/client/cli/tx.go b/x/auth/vesting/client/cli/tx.go index 8ad77b300cb6..51a8254258ef 100644 --- a/x/auth/vesting/client/cli/tx.go +++ b/x/auth/vesting/client/cli/tx.go @@ -2,6 +2,7 @@ package cli import ( "encoding/json" + "fmt" "io/ioutil" "strconv" @@ -110,11 +111,11 @@ func NewMsgCreatePeriodicVestingAccountCmd() *cobra.Command { [ { "coins": "10test", - "length_seconds":1620016673 + "length_seconds":2592000 //30 days }, { "coins": "10test", - "length_seconds":1620026673 + "length_seconds":2592000 //30 days }, ] `, @@ -143,12 +144,16 @@ func NewMsgCreatePeriodicVestingAccountCmd() *cobra.Command { var periods []types.Period - for _, p := range inputPeriods { + for i, p := range inputPeriods { amount, err := sdk.ParseCoinsNormalized(p.Coins) if err != nil { return err } + + if p.Length < 1 { + return fmt.Errorf("invalid period length of %d in period %d, length must be greater than 0", p.Length, i) + } period := types.Period{Length: p.Length, Amount: amount} periods = append(periods, period) } From 663cc4710107f22b656a47e8ee89083328d3e045 Mon Sep 17 00:00:00 2001 From: Zaki Manian Date: Sun, 20 Jun 2021 21:42:09 -0700 Subject: [PATCH 06/30] update the help message --- x/auth/vesting/client/cli/tx.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/x/auth/vesting/client/cli/tx.go b/x/auth/vesting/client/cli/tx.go index 51a8254258ef..ec3bd26a0f4b 100644 --- a/x/auth/vesting/client/cli/tx.go +++ b/x/auth/vesting/client/cli/tx.go @@ -102,8 +102,7 @@ func NewMsgCreatePeriodicVestingAccountCmd() *cobra.Command { cmd := &cobra.Command{ Use: "create-periodic-vesting-account [to_address] [periods_json_file]", Short: "Create a new vesting account funded with an allocation of tokens.", - Long: `Create a new vesting account funded with an allocation of tokens. This takes a destination address and - a period json file. + Long: `A sequence of coins and period length in seconds. Periods are sequential, in that the duration of of a period only starts at the end of the previous period. The duration of the first period starts upon account creation. For instance, the following periods.json file shows 20 "test" coins vesting 30 days apart from each other. Where periods.json contains: An array of coin strings and unix epoch times for coins to vest From 95b4f128390b19f8cff1854e07242b6ed4e3a885 Mon Sep 17 00:00:00 2001 From: Zaki Manian Date: Sat, 26 Jun 2021 22:01:28 -0700 Subject: [PATCH 07/30] Add support start time to periodic vesting account messages --- docs/core/proto-docs.md | 1 + proto/cosmos/vesting/v1beta1/tx.proto | 3 +- x/auth/vesting/client/cli/tx.go | 16 ++-- x/auth/vesting/msg_server.go | 7 +- x/auth/vesting/types/msgs.go | 7 +- x/auth/vesting/types/tx.pb.go | 103 +++++++++++++++++--------- x/slashing/types/slashing.pb.go | 15 ++-- 7 files changed, 105 insertions(+), 47 deletions(-) diff --git a/docs/core/proto-docs.md b/docs/core/proto-docs.md index 626d13bf6f06..fd931fd95ae8 100644 --- a/docs/core/proto-docs.md +++ b/docs/core/proto-docs.md @@ -8183,6 +8183,7 @@ account. | ----- | ---- | ----- | ----------- | | `from_address` | [string](#string) | | | | `to_address` | [string](#string) | | | +| `start_time` | [int64](#int64) | | | | `vesting_periods` | [Period](#cosmos.vesting.v1beta1.Period) | repeated | | diff --git a/proto/cosmos/vesting/v1beta1/tx.proto b/proto/cosmos/vesting/v1beta1/tx.proto index 63dc50299278..601ccf8788ca 100644 --- a/proto/cosmos/vesting/v1beta1/tx.proto +++ b/proto/cosmos/vesting/v1beta1/tx.proto @@ -40,5 +40,6 @@ message MsgCreatePeriodicVestingAccount { string from_address = 1 [(gogoproto.moretags) = "yaml:\"from_address\""]; string to_address = 2 [(gogoproto.moretags) = "yaml:\"to_address\""]; - repeated Period vesting_periods = 3 [(gogoproto.nullable) = false]; + int64 start_time = 3 [(gogoproto.moretags) = "yaml:\"start_time\""]; + repeated Period vesting_periods = 4 [(gogoproto.nullable) = false]; } diff --git a/x/auth/vesting/client/cli/tx.go b/x/auth/vesting/client/cli/tx.go index ec3bd26a0f4b..70cf55de4122 100644 --- a/x/auth/vesting/client/cli/tx.go +++ b/x/auth/vesting/client/cli/tx.go @@ -100,7 +100,7 @@ type InputPeriod struct { // MsgCreateVestingAccount transaction. func NewMsgCreatePeriodicVestingAccountCmd() *cobra.Command { cmd := &cobra.Command{ - Use: "create-periodic-vesting-account [to_address] [periods_json_file]", + Use: "create-periodic-vesting-account [start_time_unix] [to_address] [periods_json_file]", Short: "Create a new vesting account funded with an allocation of tokens.", Long: `A sequence of coins and period length in seconds. Periods are sequential, in that the duration of of a period only starts at the end of the previous period. The duration of the first period starts upon account creation. For instance, the following periods.json file shows 20 "test" coins vesting 30 days apart from each other. Where periods.json contains: @@ -124,19 +124,25 @@ func NewMsgCreatePeriodicVestingAccountCmd() *cobra.Command { if err != nil { return err } - toAddr, err := sdk.AccAddressFromBech32(args[0]) + + startTime, err := strconv.ParseInt(args[0], 10, 64) + + if err != nil { + return err + } + toAddr, err := sdk.AccAddressFromBech32(args[1]) if err != nil { return err } - contents, err := ioutil.ReadFile(args[1]) + contents, err := ioutil.ReadFile(args[2]) if err != nil { return err } var inputPeriods []InputPeriod - err = json.Unmarshal(contents, inputPeriods) + err = json.Unmarshal(contents, &inputPeriods) if err != nil { return err } @@ -157,7 +163,7 @@ func NewMsgCreatePeriodicVestingAccountCmd() *cobra.Command { periods = append(periods, period) } - msg := types.NewMsgCreatePeriodicVestingAccount(clientCtx.GetFromAddress(), toAddr, periods) + msg := types.NewMsgCreatePeriodicVestingAccount(clientCtx.GetFromAddress(), toAddr, startTime, periods) if err := msg.ValidateBasic(); err != nil { return err } diff --git a/x/auth/vesting/msg_server.go b/x/auth/vesting/msg_server.go index 8b95213f4b48..fabdd3098d16 100644 --- a/x/auth/vesting/msg_server.go +++ b/x/auth/vesting/msg_server.go @@ -121,6 +121,11 @@ func (s msgServer) CreatePeriodicVestingAccount(goCtx context.Context, msg *type if acc := ak.GetAccount(ctx, to); acc != nil { return nil, sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "account %s already exists", msg.ToAddress) } + + if msg.StartTime < ctx.BlockTime().Unix() { + return nil, sdkerrors.Wrapf(sdkerrors.ErrLogic, "StartTime must be after the current blocktime", msg.ToAddress) + + } var totalCoins sdk.Coins for _, period := range msg.VestingPeriods { @@ -129,7 +134,7 @@ func (s msgServer) CreatePeriodicVestingAccount(goCtx context.Context, msg *type baseAccount := ak.NewAccountWithAddress(ctx, to) - types.NewPeriodicVestingAccount(baseAccount.(*authtypes.BaseAccount), totalCoins.Sort(), ctx.BlockTime().Unix(), msg.VestingPeriods) + types.NewPeriodicVestingAccount(baseAccount.(*authtypes.BaseAccount), totalCoins.Sort(), msg.StartTime, msg.VestingPeriods) err = bk.SendCoins(ctx, from, to, totalCoins) if err != nil { diff --git a/x/auth/vesting/types/msgs.go b/x/auth/vesting/types/msgs.go index a62dee3f62c1..f4461c01420c 100644 --- a/x/auth/vesting/types/msgs.go +++ b/x/auth/vesting/types/msgs.go @@ -85,10 +85,11 @@ func (msg MsgCreateVestingAccount) GetSigners() []sdk.AccAddress { // NewMsgCreateVestingAccount returns a reference to a new MsgCreateVestingAccount. //nolint:interfacer -func NewMsgCreatePeriodicVestingAccount(fromAddr, toAddr sdk.AccAddress, periods []Period) *MsgCreatePeriodicVestingAccount { +func NewMsgCreatePeriodicVestingAccount(fromAddr, toAddr sdk.AccAddress, startTime int64, periods []Period) *MsgCreatePeriodicVestingAccount { return &MsgCreatePeriodicVestingAccount{ FromAddress: fromAddr.String(), ToAddress: toAddr.String(), + StartTime: startTime, VestingPeriods: periods, } } @@ -132,6 +133,10 @@ func (msg MsgCreatePeriodicVestingAccount) ValidateBasic() error { return sdkerrors.Wrapf(sdkerrors.ErrInvalidAddress, "invalid recipient address: %s", err) } + if msg.StartTime < 1 { + return fmt.Errorf("invalid start time of %d, length must be greater than 0", msg.StartTime) + } + for i, period := range msg.VestingPeriods { if period.Length < 1 { return fmt.Errorf("invalid period length of %d in period %d, length must be greater than 0", period.Length, i) diff --git a/x/auth/vesting/types/tx.pb.go b/x/auth/vesting/types/tx.pb.go index 41719ce8e6d3..2690a04686d6 100644 --- a/x/auth/vesting/types/tx.pb.go +++ b/x/auth/vesting/types/tx.pb.go @@ -150,7 +150,8 @@ var xxx_messageInfo_MsgCreateVestingAccountResponse proto.InternalMessageInfo type MsgCreatePeriodicVestingAccount struct { FromAddress string `protobuf:"bytes,1,opt,name=from_address,json=fromAddress,proto3" json:"from_address,omitempty" yaml:"from_address"` ToAddress string `protobuf:"bytes,2,opt,name=to_address,json=toAddress,proto3" json:"to_address,omitempty" yaml:"to_address"` - VestingPeriods []Period `protobuf:"bytes,3,rep,name=vesting_periods,json=vestingPeriods,proto3" json:"vesting_periods"` + StartTime int64 `protobuf:"varint,3,opt,name=start_time,json=startTime,proto3" json:"start_time,omitempty" yaml:"start_time"` + VestingPeriods []Period `protobuf:"bytes,4,rep,name=vesting_periods,json=vestingPeriods,proto3" json:"vesting_periods"` } func (m *MsgCreatePeriodicVestingAccount) Reset() { *m = MsgCreatePeriodicVestingAccount{} } @@ -200,6 +201,13 @@ func (m *MsgCreatePeriodicVestingAccount) GetToAddress() string { return "" } +func (m *MsgCreatePeriodicVestingAccount) GetStartTime() int64 { + if m != nil { + return m.StartTime + } + return 0 +} + func (m *MsgCreatePeriodicVestingAccount) GetVestingPeriods() []Period { if m != nil { return m.VestingPeriods @@ -216,37 +224,39 @@ func init() { func init() { proto.RegisterFile("cosmos/vesting/v1beta1/tx.proto", fileDescriptor_5338ca97811f9792) } var fileDescriptor_5338ca97811f9792 = []byte{ - // 479 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xc4, 0x53, 0x3d, 0x6f, 0xd3, 0x40, - 0x18, 0xf6, 0x25, 0xa1, 0x1f, 0x57, 0x44, 0x85, 0x5b, 0xa8, 0x89, 0x90, 0x1d, 0x2c, 0x06, 0x2f, - 0x9c, 0x49, 0x41, 0x42, 0xca, 0x56, 0x77, 0x44, 0x91, 0x90, 0x85, 0x18, 0x58, 0x22, 0xc7, 0xf7, - 0xe2, 0x9e, 0xa8, 0x7d, 0x91, 0xef, 0x52, 0x35, 0x1b, 0x3f, 0xa1, 0x3b, 0x0b, 0x33, 0xbf, 0x82, - 0xb1, 0x63, 0x47, 0xa6, 0x80, 0x92, 0xa5, 0x73, 0x7e, 0x01, 0xf2, 0xdd, 0x39, 0x74, 0x48, 0x8a, - 0x60, 0x61, 0x4a, 0x5e, 0x3f, 0x1f, 0xf7, 0xde, 0xa3, 0xe7, 0xb0, 0x97, 0x72, 0x91, 0x73, 0x11, - 0x9e, 0x81, 0x90, 0xac, 0xc8, 0xc2, 0xb3, 0xee, 0x10, 0x64, 0xd2, 0x0d, 0xe5, 0x39, 0x19, 0x95, - 0x5c, 0x72, 0xfb, 0xa1, 0x26, 0x10, 0x43, 0x20, 0x86, 0xd0, 0xde, 0xcf, 0x78, 0xc6, 0x15, 0x25, - 0xac, 0xfe, 0x69, 0x76, 0xdb, 0x35, 0x76, 0xc3, 0x44, 0xc0, 0xd2, 0x2b, 0xe5, 0xac, 0x30, 0xf8, - 0xd3, 0x35, 0xc7, 0xd5, 0xee, 0x8a, 0xe5, 0x7f, 0x6b, 0xe0, 0x83, 0xbe, 0xc8, 0x8e, 0x4b, 0x48, - 0x24, 0xbc, 0xd3, 0xd0, 0x51, 0x9a, 0xf2, 0x71, 0x21, 0xed, 0x1e, 0xbe, 0xfb, 0xa1, 0xe4, 0xf9, - 0x20, 0xa1, 0xb4, 0x04, 0x21, 0x1c, 0xd4, 0x41, 0xc1, 0x76, 0x74, 0xb0, 0x98, 0x7a, 0x7b, 0x93, - 0x24, 0x3f, 0xed, 0xf9, 0x37, 0x51, 0x3f, 0xde, 0xa9, 0xc6, 0x23, 0x3d, 0xd9, 0x2f, 0x31, 0x96, - 0x7c, 0xa9, 0x6c, 0x28, 0xe5, 0x83, 0xc5, 0xd4, 0xbb, 0xaf, 0x95, 0xbf, 0x31, 0x3f, 0xde, 0x96, - 0xbc, 0x56, 0xa5, 0x78, 0x23, 0xc9, 0xab, 0xb3, 0x9d, 0x66, 0xa7, 0x19, 0xec, 0x1c, 0x3e, 0x22, - 0x26, 0x92, 0xea, 0x92, 0x75, 0x1e, 0xe4, 0x98, 0xb3, 0x22, 0x7a, 0x7e, 0x39, 0xf5, 0xac, 0xaf, - 0x3f, 0xbc, 0x20, 0x63, 0xf2, 0x64, 0x3c, 0x24, 0x29, 0xcf, 0x43, 0x73, 0x63, 0xfd, 0xf3, 0x4c, - 0xd0, 0x8f, 0xa1, 0x9c, 0x8c, 0x40, 0x28, 0x81, 0x88, 0x8d, 0xb5, 0x4d, 0xf0, 0x16, 0x14, 0x74, - 0x20, 0x59, 0x0e, 0x4e, 0xab, 0x83, 0x82, 0x66, 0xb4, 0xb7, 0x98, 0x7a, 0xbb, 0x7a, 0xb1, 0x1a, - 0xf1, 0xe3, 0x4d, 0x28, 0xe8, 0x5b, 0x96, 0x83, 0xed, 0xe0, 0x4d, 0x0a, 0xa7, 0xc9, 0x04, 0xa8, - 0x73, 0xa7, 0x83, 0x82, 0xad, 0xb8, 0x1e, 0x7b, 0xad, 0xeb, 0x2f, 0x1e, 0xf2, 0x9f, 0x60, 0x6f, - 0x4d, 0x82, 0x31, 0x88, 0x11, 0x2f, 0x04, 0xf8, 0xd7, 0xe8, 0x06, 0xe7, 0x0d, 0x94, 0x8c, 0x53, - 0x96, 0xfe, 0xf7, 0xb4, 0xfb, 0x78, 0xd7, 0x94, 0x61, 0x30, 0x52, 0x3b, 0x09, 0x13, 0xbb, 0x4b, - 0x56, 0x37, 0x91, 0xe8, 0xd5, 0xa3, 0x56, 0x95, 0x7d, 0x7c, 0xcf, 0xa0, 0xfa, 0xa3, 0x50, 0x69, - 0x58, 0x87, 0x9f, 0x1b, 0xb8, 0xd9, 0x17, 0x99, 0xfd, 0x09, 0xe1, 0xfd, 0x95, 0xad, 0x0a, 0xd7, - 0x99, 0xaf, 0x09, 0xb1, 0xfd, 0xea, 0x2f, 0x05, 0x75, 0xea, 0xf6, 0x05, 0xc2, 0x8f, 0x6f, 0x8d, - 0xfc, 0xcf, 0xce, 0xab, 0x85, 0xff, 0xbc, 0x52, 0xf4, 0xfa, 0x72, 0xe6, 0xa2, 0xab, 0x99, 0x8b, - 0x7e, 0xce, 0x5c, 0x74, 0x31, 0x77, 0xad, 0xab, 0xb9, 0x6b, 0x7d, 0x9f, 0xbb, 0xd6, 0xfb, 0xee, - 0xad, 0x3d, 0x3e, 0x0f, 0x93, 0xb1, 0x3c, 0x59, 0xbe, 0x65, 0x55, 0xeb, 0xe1, 0x86, 0x7a, 0xc2, - 0x2f, 0x7e, 0x05, 0x00, 0x00, 0xff, 0xff, 0xaa, 0x8b, 0x7b, 0x18, 0x59, 0x04, 0x00, 0x00, + // 503 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xc4, 0x54, 0x3f, 0x6f, 0xd3, 0x40, + 0x14, 0xf7, 0xc5, 0xa1, 0x6d, 0xae, 0x88, 0x0a, 0xb7, 0x50, 0x13, 0x21, 0x3b, 0x58, 0x0c, 0x5e, + 0x38, 0x93, 0x52, 0x09, 0x29, 0x5b, 0xdd, 0x11, 0x45, 0x42, 0x16, 0x62, 0x60, 0x89, 0x2e, 0xf6, + 0xe1, 0x9e, 0xa8, 0x7d, 0x91, 0xef, 0x52, 0x35, 0x1b, 0x1f, 0xa1, 0x3b, 0x12, 0x62, 0xe6, 0x53, + 0x30, 0x76, 0xec, 0xc8, 0x14, 0x50, 0xb2, 0x30, 0xe7, 0x13, 0x20, 0xdf, 0x9d, 0xd3, 0x0c, 0x71, + 0x10, 0x2c, 0x4c, 0xc9, 0xcb, 0xef, 0xcf, 0xdd, 0xfb, 0xbd, 0x77, 0x81, 0x6e, 0xcc, 0x78, 0xc6, + 0x78, 0x70, 0x41, 0xb8, 0xa0, 0x79, 0x1a, 0x5c, 0x74, 0x87, 0x44, 0xe0, 0x6e, 0x20, 0x2e, 0xd1, + 0xa8, 0x60, 0x82, 0x59, 0x0f, 0x15, 0x01, 0x69, 0x02, 0xd2, 0x84, 0xf6, 0x41, 0xca, 0x52, 0x26, + 0x29, 0x41, 0xf9, 0x4d, 0xb1, 0xdb, 0x8e, 0xb6, 0x1b, 0x62, 0x4e, 0x96, 0x5e, 0x31, 0xa3, 0xb9, + 0xc6, 0x9f, 0xd6, 0x1c, 0x57, 0xb9, 0x4b, 0x96, 0xf7, 0xad, 0x01, 0x0f, 0xfb, 0x3c, 0x3d, 0x2d, + 0x08, 0x16, 0xe4, 0xad, 0x82, 0x4e, 0xe2, 0x98, 0x8d, 0x73, 0x61, 0xf5, 0xe0, 0xdd, 0xf7, 0x05, + 0xcb, 0x06, 0x38, 0x49, 0x0a, 0xc2, 0xb9, 0x0d, 0x3a, 0xc0, 0x6f, 0x85, 0x87, 0x8b, 0xa9, 0xbb, + 0x3f, 0xc1, 0xd9, 0x79, 0xcf, 0x5b, 0x45, 0xbd, 0x68, 0xb7, 0x2c, 0x4f, 0x54, 0x65, 0x1d, 0x43, + 0x28, 0xd8, 0x52, 0xd9, 0x90, 0xca, 0x07, 0x8b, 0xa9, 0x7b, 0x5f, 0x29, 0x6f, 0x31, 0x2f, 0x6a, + 0x09, 0x56, 0xa9, 0x62, 0xb8, 0x85, 0xb3, 0xf2, 0x6c, 0xdb, 0xec, 0x98, 0xfe, 0xee, 0xd1, 0x23, + 0xa4, 0x23, 0x29, 0x9b, 0xac, 0xf2, 0x40, 0xa7, 0x8c, 0xe6, 0xe1, 0xf3, 0xeb, 0xa9, 0x6b, 0x7c, + 0xfd, 0xe1, 0xfa, 0x29, 0x15, 0x67, 0xe3, 0x21, 0x8a, 0x59, 0x16, 0xe8, 0x8e, 0xd5, 0xc7, 0x33, + 0x9e, 0x7c, 0x08, 0xc4, 0x64, 0x44, 0xb8, 0x14, 0xf0, 0x48, 0x5b, 0x5b, 0x08, 0xee, 0x90, 0x3c, + 0x19, 0x08, 0x9a, 0x11, 0xbb, 0xd9, 0x01, 0xbe, 0x19, 0xee, 0x2f, 0xa6, 0xee, 0x9e, 0xba, 0x58, + 0x85, 0x78, 0xd1, 0x36, 0xc9, 0x93, 0x37, 0x34, 0x23, 0x96, 0x0d, 0xb7, 0x13, 0x72, 0x8e, 0x27, + 0x24, 0xb1, 0xef, 0x74, 0x80, 0xbf, 0x13, 0x55, 0x65, 0xaf, 0xf9, 0xeb, 0x8b, 0x0b, 0xbc, 0x27, + 0xd0, 0xad, 0x49, 0x30, 0x22, 0x7c, 0xc4, 0x72, 0x4e, 0xbc, 0xcf, 0x8d, 0x15, 0xce, 0x6b, 0x52, + 0x50, 0x96, 0xd0, 0xf8, 0xbf, 0xa7, 0x7d, 0x0c, 0x21, 0x17, 0xb8, 0x10, 0x2a, 0x0a, 0x53, 0x46, + 0xb1, 0xa2, 0xba, 0xc5, 0xbc, 0xa8, 0x25, 0x0b, 0x19, 0x47, 0x1f, 0xee, 0xe9, 0x15, 0x1a, 0x8c, + 0x64, 0x27, 0xdc, 0x6e, 0xca, 0x61, 0x39, 0x68, 0xfd, 0xfe, 0x22, 0xd5, 0x70, 0xd8, 0x2c, 0x27, + 0x16, 0xdd, 0xd3, 0xa8, 0xfa, 0x91, 0xcb, 0x0c, 0x8d, 0xa3, 0x4f, 0x0d, 0x68, 0xf6, 0x79, 0x6a, + 0x7d, 0x04, 0xf0, 0x60, 0xed, 0x2e, 0x06, 0x75, 0xe6, 0x35, 0xd1, 0xb7, 0x5f, 0xfe, 0xa5, 0xa0, + 0x9a, 0x95, 0x75, 0x05, 0xe0, 0xe3, 0x8d, 0x83, 0xfa, 0xb3, 0xf3, 0x7a, 0xe1, 0x3f, 0x5f, 0x29, + 0x7c, 0x75, 0x3d, 0x73, 0xc0, 0xcd, 0xcc, 0x01, 0x3f, 0x67, 0x0e, 0xb8, 0x9a, 0x3b, 0xc6, 0xcd, + 0xdc, 0x31, 0xbe, 0xcf, 0x1d, 0xe3, 0x5d, 0x77, 0xe3, 0xf6, 0x5f, 0x06, 0x78, 0x2c, 0xce, 0x96, + 0xff, 0x00, 0xf2, 0x31, 0x0c, 0xb7, 0xe4, 0xc3, 0x7f, 0xf1, 0x3b, 0x00, 0x00, 0xff, 0xff, 0x49, + 0xf6, 0x33, 0xbe, 0x8f, 0x04, 0x00, 0x00, } func (this *MsgCreateVestingAccount) Equal(that interface{}) bool { @@ -531,9 +541,14 @@ func (m *MsgCreatePeriodicVestingAccount) MarshalToSizedBuffer(dAtA []byte) (int i = encodeVarintTx(dAtA, i, uint64(size)) } i-- - dAtA[i] = 0x1a + dAtA[i] = 0x22 } } + if m.StartTime != 0 { + i = encodeVarintTx(dAtA, i, uint64(m.StartTime)) + i-- + dAtA[i] = 0x18 + } if len(m.ToAddress) > 0 { i -= len(m.ToAddress) copy(dAtA[i:], m.ToAddress) @@ -614,6 +629,9 @@ func (m *MsgCreatePeriodicVestingAccount) Size() (n int) { if l > 0 { n += 1 + l + sovTx(uint64(l)) } + if m.StartTime != 0 { + n += 1 + sovTx(uint64(m.StartTime)) + } if len(m.VestingPeriods) > 0 { for _, e := range m.VestingPeriods { l = e.Size() @@ -960,6 +978,25 @@ func (m *MsgCreatePeriodicVestingAccount) Unmarshal(dAtA []byte) error { m.ToAddress = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex case 3: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field StartTime", wireType) + } + m.StartTime = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.StartTime |= int64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 4: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field VestingPeriods", wireType) } diff --git a/x/slashing/types/slashing.pb.go b/x/slashing/types/slashing.pb.go index 1db4757a95a8..633b4c5bb944 100644 --- a/x/slashing/types/slashing.pb.go +++ b/x/slashing/types/slashing.pb.go @@ -33,16 +33,19 @@ const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package // liveness activity. type ValidatorSigningInfo struct { Address string `protobuf:"bytes,1,opt,name=address,proto3" json:"address,omitempty"` - // height at which validator was first a candidate OR was unjailed + // Height at which validator was first a candidate OR was unjailed StartHeight int64 `protobuf:"varint,2,opt,name=start_height,json=startHeight,proto3" json:"start_height,omitempty" yaml:"start_height"` - // index offset into signed block bit array + // Index which is incremented each time the validator was a bonded + // in a block and may have signed a precommit or not. This in conjunction with the + // `SignedBlocksWindow` param determines the index in the `MissedBlocksBitArray`. IndexOffset int64 `protobuf:"varint,3,opt,name=index_offset,json=indexOffset,proto3" json:"index_offset,omitempty" yaml:"index_offset"` - // timestamp validator cannot be unjailed until + // Timestamp until which the validator is jailed due to liveness downtime. JailedUntil time.Time `protobuf:"bytes,4,opt,name=jailed_until,json=jailedUntil,proto3,stdtime" json:"jailed_until" yaml:"jailed_until"` - // whether or not a validator has been tombstoned (killed out of validator - // set) + // Whether or not a validator has been tombstoned (killed out of validator set). It is set + // once the validator commits an equivocation or for any other configured misbehiavor. Tombstoned bool `protobuf:"varint,5,opt,name=tombstoned,proto3" json:"tombstoned,omitempty"` - // missed blocks counter (to avoid scanning the array every time) + // A counter kept to avoid unnecessary array reads. + // Note that `Sum(MissedBlocksBitArray)` always equals `MissedBlocksCounter`. MissedBlocksCounter int64 `protobuf:"varint,6,opt,name=missed_blocks_counter,json=missedBlocksCounter,proto3" json:"missed_blocks_counter,omitempty" yaml:"missed_blocks_counter"` } From 57f3014bb335240fd800d257c3febdc6907ef28e Mon Sep 17 00:00:00 2001 From: Zaki Manian Date: Mon, 28 Jun 2021 06:49:34 -0700 Subject: [PATCH 08/30] Add changelog entry --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index bef52a021cc3..8937386050af 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -117,6 +117,7 @@ Ref: https://keepachangelog.com/en/1.0.0/ ### State Machine Breaking +* (x/auth)[\#9596](https://github.com/cosmos/cosmos-sdk/pull/9596) Enable creating periodic vesting accounts with a transactions instead of requiring them to be created in genesis. * (x/{bank,distrib,gov,slashing,staking}) [\#8363](https://github.com/cosmos/cosmos-sdk/issues/8363) Store keys have been modified to allow for variable-length addresses. * (x/evidence) [\#8502](https://github.com/cosmos/cosmos-sdk/pull/8502) `HandleEquivocationEvidence` persists the evidence to state. * (x/gov) [\#7733](https://github.com/cosmos/cosmos-sdk/pull/7733) ADR 037 Implementation: Governance Split Votes, use `MsgWeightedVote` to send a split vote. Sending a regular `MsgVote` will convert the underlying vote option into a weighted vote with weight 1. From bfc95c2f2499bab1d40bed9ee1fe09ecd1cafa50 Mon Sep 17 00:00:00 2001 From: Zaki Manian Date: Mon, 28 Jun 2021 11:00:19 -0700 Subject: [PATCH 09/30] Update x/auth/vesting/client/cli/tx.go Co-authored-by: Aleksandr Bezobchuk --- x/auth/vesting/client/cli/tx.go | 1 - 1 file changed, 1 deletion(-) diff --git a/x/auth/vesting/client/cli/tx.go b/x/auth/vesting/client/cli/tx.go index 8bedbddd9db7..a4a22eee6f1a 100644 --- a/x/auth/vesting/client/cli/tx.go +++ b/x/auth/vesting/client/cli/tx.go @@ -119,7 +119,6 @@ func NewMsgCreatePeriodicVestingAccountCmd() *cobra.Command { } startTime, err := strconv.ParseInt(args[0], 10, 64) - if err != nil { return err } From f5c45c5ac36b3e4e838ebb237a881042d41d422a Mon Sep 17 00:00:00 2001 From: Zaki Manian Date: Mon, 28 Jun 2021 11:00:26 -0700 Subject: [PATCH 10/30] Update x/auth/vesting/client/cli/tx.go Co-authored-by: Aleksandr Bezobchuk --- x/auth/vesting/client/cli/tx.go | 1 - 1 file changed, 1 deletion(-) diff --git a/x/auth/vesting/client/cli/tx.go b/x/auth/vesting/client/cli/tx.go index a4a22eee6f1a..ac28aa4c4dcd 100644 --- a/x/auth/vesting/client/cli/tx.go +++ b/x/auth/vesting/client/cli/tx.go @@ -142,7 +142,6 @@ func NewMsgCreatePeriodicVestingAccountCmd() *cobra.Command { var periods []types.Period for i, p := range inputPeriods { - amount, err := sdk.ParseCoinsNormalized(p.Coins) if err != nil { return err From 548f4da51d5caa543314a3d7f19ed4ac42b767b9 Mon Sep 17 00:00:00 2001 From: Zaki Manian Date: Thu, 1 Jul 2021 22:53:03 -0700 Subject: [PATCH 11/30] Add starttime to the vesting input file --- x/auth/vesting/client/cli/tx.go | 31 +++++++++++++++++-------------- 1 file changed, 17 insertions(+), 14 deletions(-) diff --git a/x/auth/vesting/client/cli/tx.go b/x/auth/vesting/client/cli/tx.go index ac28aa4c4dcd..f3c756766d6d 100644 --- a/x/auth/vesting/client/cli/tx.go +++ b/x/auth/vesting/client/cli/tx.go @@ -84,6 +84,11 @@ timestamp.`, return cmd } +type VestingData struct { + StartTime int64 + Periods []InputPeriod +} + type InputPeriod struct { Coins string `json:"coins"` Length int64 `json:"length_seconds"` @@ -93,23 +98,24 @@ type InputPeriod struct { // MsgCreateVestingAccount transaction. func NewMsgCreatePeriodicVestingAccountCmd() *cobra.Command { cmd := &cobra.Command{ - Use: "create-periodic-vesting-account [start_time_unix] [to_address] [periods_json_file]", + Use: "create-periodic-vesting-account [to_address] [periods_json_file]", Short: "Create a new vesting account funded with an allocation of tokens.", Long: `A sequence of coins and period length in seconds. Periods are sequential, in that the duration of of a period only starts at the end of the previous period. The duration of the first period starts upon account creation. For instance, the following periods.json file shows 20 "test" coins vesting 30 days apart from each other. Where periods.json contains: An array of coin strings and unix epoch times for coins to vest - -[ -{ +{ "start_time": 1625204910, +"period":[ + { "coins": "10test", "length_seconds":2592000 //30 days }, { "coins": "10test", "length_seconds":2592000 //30 days - }, + }, ] + } `, Args: cobra.ExactArgs(3), RunE: func(cmd *cobra.Command, args []string) error { @@ -118,30 +124,27 @@ func NewMsgCreatePeriodicVestingAccountCmd() *cobra.Command { return err } - startTime, err := strconv.ParseInt(args[0], 10, 64) - if err != nil { - return err - } - toAddr, err := sdk.AccAddressFromBech32(args[1]) + toAddr, err := sdk.AccAddressFromBech32(args[0]) if err != nil { return err } - contents, err := ioutil.ReadFile(args[2]) + contents, err := ioutil.ReadFile(args[1]) if err != nil { return err } - var inputPeriods []InputPeriod + var vestingData VestingData - err = json.Unmarshal(contents, &inputPeriods) + err = json.Unmarshal(contents, &vestingData) if err != nil { return err } var periods []types.Period - for i, p := range inputPeriods { + for i, p := range vestingData.Periods { + amount, err := sdk.ParseCoinsNormalized(p.Coins) if err != nil { return err From ce81fc68f72963ea7ad3153d3e861822e548f247 Mon Sep 17 00:00:00 2001 From: Zaki Manian Date: Fri, 2 Jul 2021 06:58:17 -0700 Subject: [PATCH 12/30] Fix tests --- x/auth/vesting/client/cli/tx.go | 2 +- x/auth/vesting/handler_test.go | 4 ++-- x/auth/vesting/msg_server.go | 4 ---- 3 files changed, 3 insertions(+), 7 deletions(-) diff --git a/x/auth/vesting/client/cli/tx.go b/x/auth/vesting/client/cli/tx.go index f3c756766d6d..a6c40dabcf56 100644 --- a/x/auth/vesting/client/cli/tx.go +++ b/x/auth/vesting/client/cli/tx.go @@ -157,7 +157,7 @@ func NewMsgCreatePeriodicVestingAccountCmd() *cobra.Command { periods = append(periods, period) } - msg := types.NewMsgCreatePeriodicVestingAccount(clientCtx.GetFromAddress(), toAddr, startTime, periods) + msg := types.NewMsgCreatePeriodicVestingAccount(clientCtx.GetFromAddress(), toAddr, vestingData.StartTime, periods) if err := msg.ValidateBasic(); err != nil { return err } diff --git a/x/auth/vesting/handler_test.go b/x/auth/vesting/handler_test.go index 25bb4274394b..bfeb06721f8a 100644 --- a/x/auth/vesting/handler_test.go +++ b/x/auth/vesting/handler_test.go @@ -102,7 +102,7 @@ func (suite *HandlerTestSuite) TestMsgCreatePeriodicVestingAccount() { period := []types.Period{{Length: 5000, Amount: balances}} suite.app.AccountKeeper.SetAccount(ctx, acc1) - suite.Require().NoError(suite.app.BankKeeper.SetBalances(ctx, addr1, balances)) + suite.Require().NoError(simapp.FundAccount(suite.app, ctx, addr1, balances)) testCases := []struct { name string @@ -111,7 +111,7 @@ func (suite *HandlerTestSuite) TestMsgCreatePeriodicVestingAccount() { }{ { name: "continuous vesting account already exists", - msg: types.NewMsgCreatePeriodicVestingAccount(addr1, addr3, period), + msg: types.NewMsgCreatePeriodicVestingAccount(addr1, addr3, 0, period), expectErr: true, }, } diff --git a/x/auth/vesting/msg_server.go b/x/auth/vesting/msg_server.go index cd811e3e3dc2..a02514cab1e8 100644 --- a/x/auth/vesting/msg_server.go +++ b/x/auth/vesting/msg_server.go @@ -122,10 +122,6 @@ func (s msgServer) CreatePeriodicVestingAccount(goCtx context.Context, msg *type return nil, sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "account %s already exists", msg.ToAddress) } - if msg.StartTime < ctx.BlockTime().Unix() { - return nil, sdkerrors.Wrapf(sdkerrors.ErrLogic, "StartTime must be after the current blocktime", msg.ToAddress) - - } var totalCoins sdk.Coins for _, period := range msg.VestingPeriods { From 1830947e676a92d7e0f787c91ac92724a4619462 Mon Sep 17 00:00:00 2001 From: Zaki Manian Date: Fri, 2 Jul 2021 07:14:07 -0700 Subject: [PATCH 13/30] Remove the delayed flag --- x/auth/vesting/client/cli/tx.go | 1 - 1 file changed, 1 deletion(-) diff --git a/x/auth/vesting/client/cli/tx.go b/x/auth/vesting/client/cli/tx.go index a6c40dabcf56..db24175993c7 100644 --- a/x/auth/vesting/client/cli/tx.go +++ b/x/auth/vesting/client/cli/tx.go @@ -166,7 +166,6 @@ func NewMsgCreatePeriodicVestingAccountCmd() *cobra.Command { }, } - cmd.Flags().Bool(FlagDelayed, false, "Create a delayed vesting account if true") flags.AddTxFlagsToCmd(cmd) return cmd From 48640b92b19872f8809db27bca5c6d0d37415a09 Mon Sep 17 00:00:00 2001 From: Zaki Manian Date: Fri, 2 Jul 2021 12:40:42 -0700 Subject: [PATCH 14/30] add json tags --- x/auth/vesting/client/cli/tx.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/x/auth/vesting/client/cli/tx.go b/x/auth/vesting/client/cli/tx.go index db24175993c7..5ae096cab905 100644 --- a/x/auth/vesting/client/cli/tx.go +++ b/x/auth/vesting/client/cli/tx.go @@ -85,8 +85,8 @@ timestamp.`, } type VestingData struct { - StartTime int64 - Periods []InputPeriod + StartTime int64 `json:"start_time"` + Periods []InputPeriod `json:"periods"` } type InputPeriod struct { @@ -94,8 +94,8 @@ type InputPeriod struct { Length int64 `json:"length_seconds"` } -// NewMsgCreateVestingAccountCmd returns a CLI command handler for creating a -// MsgCreateVestingAccount transaction. +// NewMsgCreatePeriodicVestingAccountCmd returns a CLI command handler for creating a +// MsgCreatePeriodicVestingAccountCmd transaction. func NewMsgCreatePeriodicVestingAccountCmd() *cobra.Command { cmd := &cobra.Command{ Use: "create-periodic-vesting-account [to_address] [periods_json_file]", From 334fc1a743ca0d6acef977ed737a8b1030a8813d Mon Sep 17 00:00:00 2001 From: Zaki Manian Date: Tue, 6 Jul 2021 10:16:26 -0700 Subject: [PATCH 15/30] Update proto/cosmos/vesting/v1beta1/tx.proto Co-authored-by: Amaury <1293565+amaurym@users.noreply.github.com> --- proto/cosmos/vesting/v1beta1/tx.proto | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/proto/cosmos/vesting/v1beta1/tx.proto b/proto/cosmos/vesting/v1beta1/tx.proto index 601ccf8788ca..530ee000777a 100644 --- a/proto/cosmos/vesting/v1beta1/tx.proto +++ b/proto/cosmos/vesting/v1beta1/tx.proto @@ -12,7 +12,9 @@ service Msg { // CreateVestingAccount defines a method that enables creating a vesting // account. rpc CreateVestingAccount(MsgCreateVestingAccount) returns (MsgCreateVestingAccountResponse); - rpc CreatePeriodicVestingAccount(MsgCreatePeriodicVestingAccount) returns (MsgCreateVestingAccountResponse); + // CreatePeriodicVestingAccount defines a method that enables creating a + // periodic vesting account. + rpc CreatePeriodicVestingAccount(MsgCreatePeriodicVestingAccount) returns (MsgCreatePeriodicVestingAccountResponse); } // MsgCreateVestingAccount defines a message that enables creating a vesting From 190bf7e178ae571ce3e26894433db7cefeb634ae Mon Sep 17 00:00:00 2001 From: Zaki Manian Date: Thu, 15 Jul 2021 20:13:37 -0700 Subject: [PATCH 16/30] Update x/auth/vesting/types/msgs.go Co-authored-by: Cory --- x/auth/vesting/types/msgs.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x/auth/vesting/types/msgs.go b/x/auth/vesting/types/msgs.go index f4461c01420c..f00ac645a2d6 100644 --- a/x/auth/vesting/types/msgs.go +++ b/x/auth/vesting/types/msgs.go @@ -83,7 +83,7 @@ func (msg MsgCreateVestingAccount) GetSigners() []sdk.AccAddress { return []sdk.AccAddress{from} } -// NewMsgCreateVestingAccount returns a reference to a new MsgCreateVestingAccount. +// NewMsgCreatePeriodicVestingAccount returns a reference to a new MsgCreatePeriodicVestingAccount. //nolint:interfacer func NewMsgCreatePeriodicVestingAccount(fromAddr, toAddr sdk.AccAddress, startTime int64, periods []Period) *MsgCreatePeriodicVestingAccount { return &MsgCreatePeriodicVestingAccount{ From c74c346fd367fbac9efb041eb1f5eee8d2ea9785 Mon Sep 17 00:00:00 2001 From: Zaki Manian Date: Thu, 15 Jul 2021 20:15:28 -0700 Subject: [PATCH 17/30] Update msg_server.go actually committing the account state to periodic vesting was missing. --- x/auth/vesting/msg_server.go | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/x/auth/vesting/msg_server.go b/x/auth/vesting/msg_server.go index a02514cab1e8..e553ab453d99 100644 --- a/x/auth/vesting/msg_server.go +++ b/x/auth/vesting/msg_server.go @@ -130,7 +130,23 @@ func (s msgServer) CreatePeriodicVestingAccount(goCtx context.Context, msg *type baseAccount := ak.NewAccountWithAddress(ctx, to) - types.NewPeriodicVestingAccount(baseAccount.(*authtypes.BaseAccount), totalCoins.Sort(), msg.StartTime, msg.VestingPeriods) + acc := types.NewPeriodicVestingAccount(baseAccount.(*authtypes.BaseAccount), totalCoins.Sort(), msg.StartTime, msg.VestingPeriods) + + ak.SetAccount(ctx, acc) + + defer func() { + telemetry.IncrCounter(1, "new", "account") + + for _, a := range totalCoins { + if a.Amount.IsInt64() { + telemetry.SetGaugeWithLabels( + []string{"tx", "msg", "create_periodic_vesting_account"}, + float32(a.Amount.Int64()), + []metrics.Label{telemetry.NewLabel("denom", a.Denom)}, + ) + } + } + }() err = bk.SendCoins(ctx, from, to, totalCoins) if err != nil { From e9de0e13481847bf17873d324ed84f19522c787b Mon Sep 17 00:00:00 2001 From: Zaki Manian Date: Thu, 15 Jul 2021 20:15:38 -0700 Subject: [PATCH 18/30] Update x/auth/vesting/types/msgs.go Co-authored-by: Cory --- x/auth/vesting/types/msgs.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x/auth/vesting/types/msgs.go b/x/auth/vesting/types/msgs.go index f00ac645a2d6..9f187f80e058 100644 --- a/x/auth/vesting/types/msgs.go +++ b/x/auth/vesting/types/msgs.go @@ -110,7 +110,7 @@ func (msg MsgCreatePeriodicVestingAccount) GetSigners() []sdk.AccAddress { } // GetSignBytes returns the bytes all expected signers must sign over for a -// MsgCreateVestingAccount. +// MsgCreatePeriodicVestingAccount. func (msg MsgCreatePeriodicVestingAccount) GetSignBytes() []byte { return sdk.MustSortJSON(amino.MustMarshalJSON(&msg)) } From 873b33523c3673c6e2ac423be93a106b4c3d3fc7 Mon Sep 17 00:00:00 2001 From: Zaki Manian Date: Mon, 23 Aug 2021 08:12:55 -0700 Subject: [PATCH 19/30] Update x/auth/vesting/types/msgs.go Co-authored-by: Cory --- x/auth/vesting/types/msgs.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/x/auth/vesting/types/msgs.go b/x/auth/vesting/types/msgs.go index 9f187f80e058..37f38b42454b 100644 --- a/x/auth/vesting/types/msgs.go +++ b/x/auth/vesting/types/msgs.go @@ -94,13 +94,13 @@ func NewMsgCreatePeriodicVestingAccount(fromAddr, toAddr sdk.AccAddress, startTi } } -// Route returns the message route for a MsgCreateVestingAccount. +// Route returns the message route for a MsgCreatePeriodicVestingAccount. func (msg MsgCreatePeriodicVestingAccount) Route() string { return RouterKey } -// Type returns the message type for a MsgCreateVestingAccount. +// Type returns the message type for a MsgCreatePeriodicVestingAccount. func (msg MsgCreatePeriodicVestingAccount) Type() string { return TypeMsgCreatePeriodicVestingAccount } -// GetSigners returns the expected signers for a MsgCreateVestingAccount. +// GetSigners returns the expected signers for a MsgCreatePeriodicVestingAccount. func (msg MsgCreatePeriodicVestingAccount) GetSigners() []sdk.AccAddress { from, err := sdk.AccAddressFromBech32(msg.FromAddress) if err != nil { From 7499718354e3db7818f23b664925ee50a14e019d Mon Sep 17 00:00:00 2001 From: Zaki Manian Date: Tue, 10 Aug 2021 15:37:38 -0700 Subject: [PATCH 20/30] Add the missing type switch in NewHandler for PeriodicVestingAccounts --- x/auth/vesting/handler.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/x/auth/vesting/handler.go b/x/auth/vesting/handler.go index 1d32e9969bb5..4a3e0e013ee4 100644 --- a/x/auth/vesting/handler.go +++ b/x/auth/vesting/handler.go @@ -18,6 +18,9 @@ func NewHandler(ak keeper.AccountKeeper, bk types.BankKeeper) sdk.Handler { case *types.MsgCreateVestingAccount: res, err := msgServer.CreateVestingAccount(sdk.WrapSDKContext(ctx), msg) return sdk.WrapServiceResult(ctx, res, err) + case *types.MsgCreatePeriodicVestingAccount: + res, err := msgServer.CreatePeriodicVestingAccount(sdk.WrapSDKContext(ctx), msg) + return sdk.WrapServiceResult(ctx, res, err) default: return nil, sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "unrecognized %s message type: %T", types.ModuleName, msg) From b7cd77a7580d188bfd0612796af31b59fb345a02 Mon Sep 17 00:00:00 2001 From: Zaki Manian Date: Tue, 10 Aug 2021 15:24:11 -0700 Subject: [PATCH 21/30] Fix the computation of total coins --- x/auth/vesting/msg_server.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x/auth/vesting/msg_server.go b/x/auth/vesting/msg_server.go index e553ab453d99..224e2c4d907a 100644 --- a/x/auth/vesting/msg_server.go +++ b/x/auth/vesting/msg_server.go @@ -125,7 +125,7 @@ func (s msgServer) CreatePeriodicVestingAccount(goCtx context.Context, msg *type var totalCoins sdk.Coins for _, period := range msg.VestingPeriods { - totalCoins.Add(period.Amount...) + totalCoins = totalCoins.Add(period.Amount...) } baseAccount := ak.NewAccountWithAddress(ctx, to) From 4d43a623bf02265d8e5bf727fdfb5721f3ad84b2 Mon Sep 17 00:00:00 2001 From: Zaki Manian Date: Tue, 10 Aug 2021 15:53:23 -0700 Subject: [PATCH 22/30] bug! add unit test --- x/auth/vesting/handler_test.go | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/x/auth/vesting/handler_test.go b/x/auth/vesting/handler_test.go index bfeb06721f8a..cda1263f6b73 100644 --- a/x/auth/vesting/handler_test.go +++ b/x/auth/vesting/handler_test.go @@ -110,9 +110,9 @@ func (suite *HandlerTestSuite) TestMsgCreatePeriodicVestingAccount() { expectErr bool }{ { - name: "continuous vesting account already exists", + name: "create periodic vesting account", msg: types.NewMsgCreatePeriodicVestingAccount(addr1, addr3, 0, period), - expectErr: true, + expectErr: false, }, } @@ -128,9 +128,15 @@ func (suite *HandlerTestSuite) TestMsgCreatePeriodicVestingAccount() { suite.Require().NotNil(res) toAddr, err := sdk.AccAddressFromBech32(tc.msg.ToAddress) + + suite.Require().NoError(err) + fromAddr, err := sdk.AccAddressFromBech32(tc.msg.FromAddress) suite.Require().NoError(err) + accI := suite.app.AccountKeeper.GetAccount(ctx, toAddr) suite.Require().NotNil(accI) + balance := suite.app.BankKeeper.GetBalance(ctx, fromAddr, "test") + suite.Require().Equal(balance, sdk.NewInt64Coin("test", 0)) } }) From 42f6ca0064d2a719cd9c14b6dea943691a68c2f6 Mon Sep 17 00:00:00 2001 From: Zaki Manian Date: Mon, 23 Aug 2021 08:30:29 -0700 Subject: [PATCH 23/30] move changelog entry --- CHANGELOG.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8937386050af..a5309bbd2bb0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -41,6 +41,9 @@ Ref: https://keepachangelog.com/en/1.0.0/ * (client/tx) [\#9421](https://github.com/cosmos/cosmos-sdk/pull/9421/) `BuildUnsignedTx`, `BuildSimTx`, `PrintUnsignedStdTx` functions are moved to the Tx Factory as methods. +### State Machine Breaking Changes +* (x/auth)[\#9596](https://github.com/cosmos/cosmos-sdk/pull/9596) Enable creating periodic vesting accounts with a transactions instead of requiring them to be created in genesis. + ## [v0.43.0-rc0](https://github.com/cosmos/cosmos-sdk/releases/tag/v0.43.0-rc0) - 2021-06-25 ### Features @@ -117,7 +120,6 @@ Ref: https://keepachangelog.com/en/1.0.0/ ### State Machine Breaking -* (x/auth)[\#9596](https://github.com/cosmos/cosmos-sdk/pull/9596) Enable creating periodic vesting accounts with a transactions instead of requiring them to be created in genesis. * (x/{bank,distrib,gov,slashing,staking}) [\#8363](https://github.com/cosmos/cosmos-sdk/issues/8363) Store keys have been modified to allow for variable-length addresses. * (x/evidence) [\#8502](https://github.com/cosmos/cosmos-sdk/pull/8502) `HandleEquivocationEvidence` persists the evidence to state. * (x/gov) [\#7733](https://github.com/cosmos/cosmos-sdk/pull/7733) ADR 037 Implementation: Governance Split Votes, use `MsgWeightedVote` to send a split vote. Sending a regular `MsgVote` will convert the underlying vote option into a weighted vote with weight 1. From 7a7fb4c042e105fd77e6284e9ec0d21d469b8029 Mon Sep 17 00:00:00 2001 From: Zaki Manian Date: Mon, 23 Aug 2021 08:36:06 -0700 Subject: [PATCH 24/30] Add MsgCreatePeriodicVestingAccountResponse --- docs/core/proto-docs.md | 13 +- proto/cosmos/vesting/v1beta1/tx.proto | 2 + x/auth/vesting/handler_test.go | 2 +- x/auth/vesting/types/tx.pb.go | 202 +++++++++++++++++++++----- 4 files changed, 179 insertions(+), 40 deletions(-) diff --git a/docs/core/proto-docs.md b/docs/core/proto-docs.md index ca79592a518f..5a19f91958ea 100644 --- a/docs/core/proto-docs.md +++ b/docs/core/proto-docs.md @@ -581,6 +581,7 @@ - [cosmos/vesting/v1beta1/tx.proto](#cosmos/vesting/v1beta1/tx.proto) - [MsgCreatePeriodicVestingAccount](#cosmos.vesting.v1beta1.MsgCreatePeriodicVestingAccount) + - [MsgCreatePeriodicVestingAccountResponse](#cosmos.vesting.v1beta1.MsgCreatePeriodicVestingAccountResponse) - [MsgCreateVestingAccount](#cosmos.vesting.v1beta1.MsgCreateVestingAccount) - [MsgCreateVestingAccountResponse](#cosmos.vesting.v1beta1.MsgCreateVestingAccountResponse) @@ -8211,6 +8212,16 @@ account. + + +### MsgCreatePeriodicVestingAccountResponse + + + + + + + ### MsgCreateVestingAccount @@ -8255,7 +8266,7 @@ Msg defines the bank Msg service. | Method Name | Request Type | Response Type | Description | HTTP Verb | Endpoint | | ----------- | ------------ | ------------- | ------------| ------- | -------- | | `CreateVestingAccount` | [MsgCreateVestingAccount](#cosmos.vesting.v1beta1.MsgCreateVestingAccount) | [MsgCreateVestingAccountResponse](#cosmos.vesting.v1beta1.MsgCreateVestingAccountResponse) | CreateVestingAccount defines a method that enables creating a vesting account. | | -| `CreatePeriodicVestingAccount` | [MsgCreatePeriodicVestingAccount](#cosmos.vesting.v1beta1.MsgCreatePeriodicVestingAccount) | [MsgCreateVestingAccountResponse](#cosmos.vesting.v1beta1.MsgCreateVestingAccountResponse) | | | +| `CreatePeriodicVestingAccount` | [MsgCreatePeriodicVestingAccount](#cosmos.vesting.v1beta1.MsgCreatePeriodicVestingAccount) | [MsgCreatePeriodicVestingAccountResponse](#cosmos.vesting.v1beta1.MsgCreatePeriodicVestingAccountResponse) | CreatePeriodicVestingAccount defines a method that enables creating a periodic vesting account. | | diff --git a/proto/cosmos/vesting/v1beta1/tx.proto b/proto/cosmos/vesting/v1beta1/tx.proto index 530ee000777a..8cd4eb7a48d1 100644 --- a/proto/cosmos/vesting/v1beta1/tx.proto +++ b/proto/cosmos/vesting/v1beta1/tx.proto @@ -45,3 +45,5 @@ message MsgCreatePeriodicVestingAccount { int64 start_time = 3 [(gogoproto.moretags) = "yaml:\"start_time\""]; repeated Period vesting_periods = 4 [(gogoproto.nullable) = false]; } + +message MsgCreatePeriodicVestingAccountResponse {} diff --git a/x/auth/vesting/handler_test.go b/x/auth/vesting/handler_test.go index cda1263f6b73..6b36ff058343 100644 --- a/x/auth/vesting/handler_test.go +++ b/x/auth/vesting/handler_test.go @@ -102,7 +102,7 @@ func (suite *HandlerTestSuite) TestMsgCreatePeriodicVestingAccount() { period := []types.Period{{Length: 5000, Amount: balances}} suite.app.AccountKeeper.SetAccount(ctx, acc1) - suite.Require().NoError(simapp.FundAccount(suite.app, ctx, addr1, balances)) + suite.Require().NoError(simapp.FundAccount(suite.app.BankKeeper, ctx, addr1, balances)) testCases := []struct { name string diff --git a/x/auth/vesting/types/tx.pb.go b/x/auth/vesting/types/tx.pb.go index 2690a04686d6..1124087de5d7 100644 --- a/x/auth/vesting/types/tx.pb.go +++ b/x/auth/vesting/types/tx.pb.go @@ -215,48 +215,88 @@ func (m *MsgCreatePeriodicVestingAccount) GetVestingPeriods() []Period { return nil } +type MsgCreatePeriodicVestingAccountResponse struct { +} + +func (m *MsgCreatePeriodicVestingAccountResponse) Reset() { + *m = MsgCreatePeriodicVestingAccountResponse{} +} +func (m *MsgCreatePeriodicVestingAccountResponse) String() string { return proto.CompactTextString(m) } +func (*MsgCreatePeriodicVestingAccountResponse) ProtoMessage() {} +func (*MsgCreatePeriodicVestingAccountResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_5338ca97811f9792, []int{3} +} +func (m *MsgCreatePeriodicVestingAccountResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MsgCreatePeriodicVestingAccountResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MsgCreatePeriodicVestingAccountResponse.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 *MsgCreatePeriodicVestingAccountResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_MsgCreatePeriodicVestingAccountResponse.Merge(m, src) +} +func (m *MsgCreatePeriodicVestingAccountResponse) XXX_Size() int { + return m.Size() +} +func (m *MsgCreatePeriodicVestingAccountResponse) XXX_DiscardUnknown() { + xxx_messageInfo_MsgCreatePeriodicVestingAccountResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_MsgCreatePeriodicVestingAccountResponse proto.InternalMessageInfo + func init() { proto.RegisterType((*MsgCreateVestingAccount)(nil), "cosmos.vesting.v1beta1.MsgCreateVestingAccount") proto.RegisterType((*MsgCreateVestingAccountResponse)(nil), "cosmos.vesting.v1beta1.MsgCreateVestingAccountResponse") proto.RegisterType((*MsgCreatePeriodicVestingAccount)(nil), "cosmos.vesting.v1beta1.MsgCreatePeriodicVestingAccount") + proto.RegisterType((*MsgCreatePeriodicVestingAccountResponse)(nil), "cosmos.vesting.v1beta1.MsgCreatePeriodicVestingAccountResponse") } func init() { proto.RegisterFile("cosmos/vesting/v1beta1/tx.proto", fileDescriptor_5338ca97811f9792) } var fileDescriptor_5338ca97811f9792 = []byte{ - // 503 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xc4, 0x54, 0x3f, 0x6f, 0xd3, 0x40, - 0x14, 0xf7, 0xc5, 0xa1, 0x6d, 0xae, 0x88, 0x0a, 0xb7, 0x50, 0x13, 0x21, 0x3b, 0x58, 0x0c, 0x5e, - 0x38, 0x93, 0x52, 0x09, 0x29, 0x5b, 0xdd, 0x11, 0x45, 0x42, 0x16, 0x62, 0x60, 0x89, 0x2e, 0xf6, - 0xe1, 0x9e, 0xa8, 0x7d, 0x91, 0xef, 0x52, 0x35, 0x1b, 0x1f, 0xa1, 0x3b, 0x12, 0x62, 0xe6, 0x53, - 0x30, 0x76, 0xec, 0xc8, 0x14, 0x50, 0xb2, 0x30, 0xe7, 0x13, 0x20, 0xdf, 0x9d, 0xd3, 0x0c, 0x71, - 0x10, 0x2c, 0x4c, 0xc9, 0xcb, 0xef, 0xcf, 0xdd, 0xfb, 0xbd, 0x77, 0x81, 0x6e, 0xcc, 0x78, 0xc6, - 0x78, 0x70, 0x41, 0xb8, 0xa0, 0x79, 0x1a, 0x5c, 0x74, 0x87, 0x44, 0xe0, 0x6e, 0x20, 0x2e, 0xd1, - 0xa8, 0x60, 0x82, 0x59, 0x0f, 0x15, 0x01, 0x69, 0x02, 0xd2, 0x84, 0xf6, 0x41, 0xca, 0x52, 0x26, - 0x29, 0x41, 0xf9, 0x4d, 0xb1, 0xdb, 0x8e, 0xb6, 0x1b, 0x62, 0x4e, 0x96, 0x5e, 0x31, 0xa3, 0xb9, - 0xc6, 0x9f, 0xd6, 0x1c, 0x57, 0xb9, 0x4b, 0x96, 0xf7, 0xad, 0x01, 0x0f, 0xfb, 0x3c, 0x3d, 0x2d, - 0x08, 0x16, 0xe4, 0xad, 0x82, 0x4e, 0xe2, 0x98, 0x8d, 0x73, 0x61, 0xf5, 0xe0, 0xdd, 0xf7, 0x05, - 0xcb, 0x06, 0x38, 0x49, 0x0a, 0xc2, 0xb9, 0x0d, 0x3a, 0xc0, 0x6f, 0x85, 0x87, 0x8b, 0xa9, 0xbb, - 0x3f, 0xc1, 0xd9, 0x79, 0xcf, 0x5b, 0x45, 0xbd, 0x68, 0xb7, 0x2c, 0x4f, 0x54, 0x65, 0x1d, 0x43, - 0x28, 0xd8, 0x52, 0xd9, 0x90, 0xca, 0x07, 0x8b, 0xa9, 0x7b, 0x5f, 0x29, 0x6f, 0x31, 0x2f, 0x6a, - 0x09, 0x56, 0xa9, 0x62, 0xb8, 0x85, 0xb3, 0xf2, 0x6c, 0xdb, 0xec, 0x98, 0xfe, 0xee, 0xd1, 0x23, - 0xa4, 0x23, 0x29, 0x9b, 0xac, 0xf2, 0x40, 0xa7, 0x8c, 0xe6, 0xe1, 0xf3, 0xeb, 0xa9, 0x6b, 0x7c, - 0xfd, 0xe1, 0xfa, 0x29, 0x15, 0x67, 0xe3, 0x21, 0x8a, 0x59, 0x16, 0xe8, 0x8e, 0xd5, 0xc7, 0x33, - 0x9e, 0x7c, 0x08, 0xc4, 0x64, 0x44, 0xb8, 0x14, 0xf0, 0x48, 0x5b, 0x5b, 0x08, 0xee, 0x90, 0x3c, - 0x19, 0x08, 0x9a, 0x11, 0xbb, 0xd9, 0x01, 0xbe, 0x19, 0xee, 0x2f, 0xa6, 0xee, 0x9e, 0xba, 0x58, - 0x85, 0x78, 0xd1, 0x36, 0xc9, 0x93, 0x37, 0x34, 0x23, 0x96, 0x0d, 0xb7, 0x13, 0x72, 0x8e, 0x27, - 0x24, 0xb1, 0xef, 0x74, 0x80, 0xbf, 0x13, 0x55, 0x65, 0xaf, 0xf9, 0xeb, 0x8b, 0x0b, 0xbc, 0x27, - 0xd0, 0xad, 0x49, 0x30, 0x22, 0x7c, 0xc4, 0x72, 0x4e, 0xbc, 0xcf, 0x8d, 0x15, 0xce, 0x6b, 0x52, - 0x50, 0x96, 0xd0, 0xf8, 0xbf, 0xa7, 0x7d, 0x0c, 0x21, 0x17, 0xb8, 0x10, 0x2a, 0x0a, 0x53, 0x46, - 0xb1, 0xa2, 0xba, 0xc5, 0xbc, 0xa8, 0x25, 0x0b, 0x19, 0x47, 0x1f, 0xee, 0xe9, 0x15, 0x1a, 0x8c, - 0x64, 0x27, 0xdc, 0x6e, 0xca, 0x61, 0x39, 0x68, 0xfd, 0xfe, 0x22, 0xd5, 0x70, 0xd8, 0x2c, 0x27, - 0x16, 0xdd, 0xd3, 0xa8, 0xfa, 0x91, 0xcb, 0x0c, 0x8d, 0xa3, 0x4f, 0x0d, 0x68, 0xf6, 0x79, 0x6a, - 0x7d, 0x04, 0xf0, 0x60, 0xed, 0x2e, 0x06, 0x75, 0xe6, 0x35, 0xd1, 0xb7, 0x5f, 0xfe, 0xa5, 0xa0, - 0x9a, 0x95, 0x75, 0x05, 0xe0, 0xe3, 0x8d, 0x83, 0xfa, 0xb3, 0xf3, 0x7a, 0xe1, 0x3f, 0x5f, 0x29, - 0x7c, 0x75, 0x3d, 0x73, 0xc0, 0xcd, 0xcc, 0x01, 0x3f, 0x67, 0x0e, 0xb8, 0x9a, 0x3b, 0xc6, 0xcd, - 0xdc, 0x31, 0xbe, 0xcf, 0x1d, 0xe3, 0x5d, 0x77, 0xe3, 0xf6, 0x5f, 0x06, 0x78, 0x2c, 0xce, 0x96, - 0xff, 0x00, 0xf2, 0x31, 0x0c, 0xb7, 0xe4, 0xc3, 0x7f, 0xf1, 0x3b, 0x00, 0x00, 0xff, 0xff, 0x49, - 0xf6, 0x33, 0xbe, 0x8f, 0x04, 0x00, 0x00, + // 519 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xc4, 0x54, 0x31, 0x6f, 0xd3, 0x40, + 0x14, 0xf6, 0xc5, 0xa1, 0x6d, 0xae, 0x88, 0x0a, 0xb7, 0x50, 0x13, 0x21, 0x3b, 0x9c, 0x90, 0x30, + 0x03, 0x67, 0x52, 0x2a, 0x21, 0x65, 0x41, 0x75, 0x47, 0x14, 0x09, 0x59, 0x88, 0x81, 0x25, 0xba, + 0xd8, 0x87, 0x6b, 0x51, 0xfb, 0x22, 0xdf, 0xa5, 0x6a, 0x36, 0x7e, 0x02, 0x23, 0x13, 0x42, 0x62, + 0xe3, 0x57, 0x30, 0x76, 0xec, 0xc8, 0x14, 0x50, 0xb2, 0x30, 0xe7, 0x17, 0x20, 0xdf, 0x9d, 0xd3, + 0x0c, 0x49, 0x23, 0x58, 0x98, 0x92, 0xe7, 0xef, 0xfb, 0xde, 0xbd, 0xf7, 0xbd, 0x77, 0x07, 0xdd, + 0x88, 0xf1, 0x8c, 0x71, 0xff, 0x8c, 0x72, 0x91, 0xe6, 0x89, 0x7f, 0xd6, 0xee, 0x53, 0x41, 0xda, + 0xbe, 0x38, 0xc7, 0x83, 0x82, 0x09, 0x66, 0xdd, 0x55, 0x04, 0xac, 0x09, 0x58, 0x13, 0x9a, 0x7b, + 0x09, 0x4b, 0x98, 0xa4, 0xf8, 0xe5, 0x3f, 0xc5, 0x6e, 0x3a, 0x3a, 0x5d, 0x9f, 0x70, 0x3a, 0xcf, + 0x15, 0xb1, 0x34, 0xd7, 0xf8, 0xc3, 0x15, 0xc7, 0x55, 0xd9, 0x25, 0x0b, 0x7d, 0xaf, 0xc1, 0xfd, + 0x2e, 0x4f, 0x8e, 0x0b, 0x4a, 0x04, 0x7d, 0xa3, 0xa0, 0xa3, 0x28, 0x62, 0xc3, 0x5c, 0x58, 0x1d, + 0x78, 0xf3, 0x5d, 0xc1, 0xb2, 0x1e, 0x89, 0xe3, 0x82, 0x72, 0x6e, 0x83, 0x16, 0xf0, 0x1a, 0xc1, + 0xfe, 0x6c, 0xec, 0xee, 0x8e, 0x48, 0x76, 0xda, 0x41, 0x8b, 0x28, 0x0a, 0xb7, 0xcb, 0xf0, 0x48, + 0x45, 0xd6, 0x21, 0x84, 0x82, 0xcd, 0x95, 0x35, 0xa9, 0xbc, 0x33, 0x1b, 0xbb, 0xb7, 0x95, 0xf2, + 0x0a, 0x43, 0x61, 0x43, 0xb0, 0x4a, 0x15, 0xc1, 0x0d, 0x92, 0x95, 0x67, 0xdb, 0x66, 0xcb, 0xf4, + 0xb6, 0x0f, 0xee, 0x61, 0x6d, 0x49, 0xd9, 0x64, 0xe5, 0x07, 0x3e, 0x66, 0x69, 0x1e, 0x3c, 0xbd, + 0x18, 0xbb, 0xc6, 0xb7, 0x9f, 0xae, 0x97, 0xa4, 0xe2, 0x64, 0xd8, 0xc7, 0x11, 0xcb, 0x7c, 0xdd, + 0xb1, 0xfa, 0x79, 0xc2, 0xe3, 0xf7, 0xbe, 0x18, 0x0d, 0x28, 0x97, 0x02, 0x1e, 0xea, 0xd4, 0x16, + 0x86, 0x5b, 0x34, 0x8f, 0x7b, 0x22, 0xcd, 0xa8, 0x5d, 0x6f, 0x01, 0xcf, 0x0c, 0x76, 0x67, 0x63, + 0x77, 0x47, 0x15, 0x56, 0x21, 0x28, 0xdc, 0xa4, 0x79, 0xfc, 0x3a, 0xcd, 0xa8, 0x65, 0xc3, 0xcd, + 0x98, 0x9e, 0x92, 0x11, 0x8d, 0xed, 0x1b, 0x2d, 0xe0, 0x6d, 0x85, 0x55, 0xd8, 0xa9, 0xff, 0xfe, + 0xe2, 0x02, 0xf4, 0x00, 0xba, 0x2b, 0x1c, 0x0c, 0x29, 0x1f, 0xb0, 0x9c, 0x53, 0xf4, 0xb9, 0xb6, + 0xc0, 0x79, 0x45, 0x8b, 0x94, 0xc5, 0x69, 0xf4, 0xdf, 0xdd, 0x3e, 0x84, 0x90, 0x0b, 0x52, 0x08, + 0x65, 0x85, 0x29, 0xad, 0x58, 0x50, 0x5d, 0x61, 0x28, 0x6c, 0xc8, 0x40, 0xda, 0xd1, 0x85, 0x3b, + 0x7a, 0x85, 0x7a, 0x03, 0xd9, 0x09, 0xb7, 0xeb, 0x72, 0x58, 0x0e, 0x5e, 0xbe, 0xbf, 0x58, 0x35, + 0x1c, 0xd4, 0xcb, 0x89, 0x85, 0xb7, 0x34, 0xaa, 0x3e, 0x72, 0xe9, 0xa1, 0x81, 0x1e, 0xc3, 0x47, + 0x6b, 0xfc, 0xa9, 0xbc, 0x3c, 0xf8, 0x5a, 0x83, 0x66, 0x97, 0x27, 0xd6, 0x07, 0x00, 0xf7, 0x96, + 0xae, 0xad, 0xbf, 0xaa, 0x8e, 0x15, 0x53, 0x6a, 0x3e, 0xff, 0x4b, 0x41, 0x55, 0x8a, 0xf5, 0x09, + 0xc0, 0xfb, 0xd7, 0xce, 0x74, 0x7d, 0xe6, 0xe5, 0xc2, 0xe6, 0x8b, 0x7f, 0x14, 0x56, 0xa5, 0x05, + 0x2f, 0x2f, 0x26, 0x0e, 0xb8, 0x9c, 0x38, 0xe0, 0xd7, 0xc4, 0x01, 0x1f, 0xa7, 0x8e, 0x71, 0x39, + 0x75, 0x8c, 0x1f, 0x53, 0xc7, 0x78, 0xdb, 0xbe, 0xf6, 0xc2, 0x9c, 0xfb, 0x64, 0x28, 0x4e, 0xe6, + 0x8f, 0x86, 0xbc, 0x3f, 0xfd, 0x0d, 0xf9, 0x56, 0x3c, 0xfb, 0x13, 0x00, 0x00, 0xff, 0xff, 0x28, + 0x5a, 0x9c, 0x7b, 0xc2, 0x04, 0x00, 0x00, } func (this *MsgCreateVestingAccount) Equal(that interface{}) bool { @@ -316,7 +356,9 @@ type MsgClient interface { // CreateVestingAccount defines a method that enables creating a vesting // account. CreateVestingAccount(ctx context.Context, in *MsgCreateVestingAccount, opts ...grpc.CallOption) (*MsgCreateVestingAccountResponse, error) - CreatePeriodicVestingAccount(ctx context.Context, in *MsgCreatePeriodicVestingAccount, opts ...grpc.CallOption) (*MsgCreateVestingAccountResponse, error) + // CreatePeriodicVestingAccount defines a method that enables creating a + // periodic vesting account. + CreatePeriodicVestingAccount(ctx context.Context, in *MsgCreatePeriodicVestingAccount, opts ...grpc.CallOption) (*MsgCreatePeriodicVestingAccountResponse, error) } type msgClient struct { @@ -336,8 +378,8 @@ func (c *msgClient) CreateVestingAccount(ctx context.Context, in *MsgCreateVesti return out, nil } -func (c *msgClient) CreatePeriodicVestingAccount(ctx context.Context, in *MsgCreatePeriodicVestingAccount, opts ...grpc.CallOption) (*MsgCreateVestingAccountResponse, error) { - out := new(MsgCreateVestingAccountResponse) +func (c *msgClient) CreatePeriodicVestingAccount(ctx context.Context, in *MsgCreatePeriodicVestingAccount, opts ...grpc.CallOption) (*MsgCreatePeriodicVestingAccountResponse, error) { + out := new(MsgCreatePeriodicVestingAccountResponse) err := c.cc.Invoke(ctx, "/cosmos.vesting.v1beta1.Msg/CreatePeriodicVestingAccount", in, out, opts...) if err != nil { return nil, err @@ -350,7 +392,9 @@ type MsgServer interface { // CreateVestingAccount defines a method that enables creating a vesting // account. CreateVestingAccount(context.Context, *MsgCreateVestingAccount) (*MsgCreateVestingAccountResponse, error) - CreatePeriodicVestingAccount(context.Context, *MsgCreatePeriodicVestingAccount) (*MsgCreateVestingAccountResponse, error) + // CreatePeriodicVestingAccount defines a method that enables creating a + // periodic vesting account. + CreatePeriodicVestingAccount(context.Context, *MsgCreatePeriodicVestingAccount) (*MsgCreatePeriodicVestingAccountResponse, error) } // UnimplementedMsgServer can be embedded to have forward compatible implementations. @@ -360,7 +404,7 @@ type UnimplementedMsgServer struct { func (*UnimplementedMsgServer) CreateVestingAccount(ctx context.Context, req *MsgCreateVestingAccount) (*MsgCreateVestingAccountResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method CreateVestingAccount not implemented") } -func (*UnimplementedMsgServer) CreatePeriodicVestingAccount(ctx context.Context, req *MsgCreatePeriodicVestingAccount) (*MsgCreateVestingAccountResponse, error) { +func (*UnimplementedMsgServer) CreatePeriodicVestingAccount(ctx context.Context, req *MsgCreatePeriodicVestingAccount) (*MsgCreatePeriodicVestingAccountResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method CreatePeriodicVestingAccount not implemented") } @@ -566,6 +610,29 @@ func (m *MsgCreatePeriodicVestingAccount) MarshalToSizedBuffer(dAtA []byte) (int return len(dAtA) - i, nil } +func (m *MsgCreatePeriodicVestingAccountResponse) 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 *MsgCreatePeriodicVestingAccountResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MsgCreatePeriodicVestingAccountResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + return len(dAtA) - i, nil +} + func encodeVarintTx(dAtA []byte, offset int, v uint64) int { offset -= sovTx(v) base := offset @@ -641,6 +708,15 @@ func (m *MsgCreatePeriodicVestingAccount) Size() (n int) { return n } +func (m *MsgCreatePeriodicVestingAccountResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + return n +} + func sovTx(x uint64) (n int) { return (math_bits.Len64(x|1) + 6) / 7 } @@ -1051,6 +1127,56 @@ func (m *MsgCreatePeriodicVestingAccount) Unmarshal(dAtA []byte) error { } return nil } +func (m *MsgCreatePeriodicVestingAccountResponse) 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 ErrIntOverflowTx + } + 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: MsgCreatePeriodicVestingAccountResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MsgCreatePeriodicVestingAccountResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + default: + iNdEx = preIndex + skippy, err := skipTx(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthTx + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} func skipTx(dAtA []byte) (n int, err error) { l := len(dAtA) iNdEx := 0 From 954953fd8f5a6c16e98261025b512ec26a0ef2d8 Mon Sep 17 00:00:00 2001 From: Zaki Manian Date: Mon, 23 Aug 2021 08:41:33 -0700 Subject: [PATCH 25/30] Remove redundant blocked account check --- x/auth/vesting/msg_server.go | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/x/auth/vesting/msg_server.go b/x/auth/vesting/msg_server.go index 224e2c4d907a..5557b96ba4a3 100644 --- a/x/auth/vesting/msg_server.go +++ b/x/auth/vesting/msg_server.go @@ -99,7 +99,7 @@ func (s msgServer) CreateVestingAccount(goCtx context.Context, msg *types.MsgCre return &types.MsgCreateVestingAccountResponse{}, nil } -func (s msgServer) CreatePeriodicVestingAccount(goCtx context.Context, msg *types.MsgCreatePeriodicVestingAccount) (*types.MsgCreateVestingAccountResponse, error) { +func (s msgServer) CreatePeriodicVestingAccount(goCtx context.Context, msg *types.MsgCreatePeriodicVestingAccount) (*types.MsgCreatePeriodicVestingAccountResponse, error) { ctx := sdk.UnwrapSDKContext(goCtx) ak := s.AccountKeeper @@ -114,10 +114,6 @@ func (s msgServer) CreatePeriodicVestingAccount(goCtx context.Context, msg *type return nil, err } - if bk.BlockedAddr(to) { - return nil, sdkerrors.Wrapf(sdkerrors.ErrUnauthorized, "%s is not allowed to receive funds", msg.ToAddress) - } - if acc := ak.GetAccount(ctx, to); acc != nil { return nil, sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "account %s already exists", msg.ToAddress) } @@ -159,6 +155,6 @@ func (s msgServer) CreatePeriodicVestingAccount(goCtx context.Context, msg *type sdk.NewAttribute(sdk.AttributeKeyModule, types.AttributeValueCategory), ), ) - return &types.MsgCreateVestingAccountResponse{}, nil + return &types.MsgCreatePeriodicVestingAccountResponse{}, nil } From 6039fd81c1bb0df56fb99abbb076528bfec61f02 Mon Sep 17 00:00:00 2001 From: Zaki Manian Date: Mon, 23 Aug 2021 08:51:51 -0700 Subject: [PATCH 26/30] Allow period lengths of zero --- x/auth/vesting/client/cli/tx.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x/auth/vesting/client/cli/tx.go b/x/auth/vesting/client/cli/tx.go index 5ae096cab905..e0ec5eff2d7b 100644 --- a/x/auth/vesting/client/cli/tx.go +++ b/x/auth/vesting/client/cli/tx.go @@ -150,7 +150,7 @@ func NewMsgCreatePeriodicVestingAccountCmd() *cobra.Command { return err } - if p.Length < 1 { + if p.Length < 0 { return fmt.Errorf("invalid period length of %d in period %d, length must be greater than 0", p.Length, i) } period := types.Period{Length: p.Length, Amount: amount} From 9f978b6255fea5ab8ecce3d117791b1e53a23532 Mon Sep 17 00:00:00 2001 From: Zaki Manian Date: Mon, 23 Aug 2021 08:58:15 -0700 Subject: [PATCH 27/30] Remove handlers --- x/auth/vesting/handler.go | 29 ------- x/auth/vesting/handler_test.go | 148 --------------------------------- 2 files changed, 177 deletions(-) delete mode 100644 x/auth/vesting/handler.go delete mode 100644 x/auth/vesting/handler_test.go diff --git a/x/auth/vesting/handler.go b/x/auth/vesting/handler.go deleted file mode 100644 index 4a3e0e013ee4..000000000000 --- a/x/auth/vesting/handler.go +++ /dev/null @@ -1,29 +0,0 @@ -package vesting - -import ( - sdk "github.com/cosmos/cosmos-sdk/types" - sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" - "github.com/cosmos/cosmos-sdk/x/auth/keeper" - "github.com/cosmos/cosmos-sdk/x/auth/vesting/types" -) - -// NewHandler returns a handler for x/auth message types. -func NewHandler(ak keeper.AccountKeeper, bk types.BankKeeper) sdk.Handler { - msgServer := NewMsgServerImpl(ak, bk) - - return func(ctx sdk.Context, msg sdk.Msg) (*sdk.Result, error) { - ctx = ctx.WithEventManager(sdk.NewEventManager()) - - switch msg := msg.(type) { - case *types.MsgCreateVestingAccount: - res, err := msgServer.CreateVestingAccount(sdk.WrapSDKContext(ctx), msg) - return sdk.WrapServiceResult(ctx, res, err) - case *types.MsgCreatePeriodicVestingAccount: - res, err := msgServer.CreatePeriodicVestingAccount(sdk.WrapSDKContext(ctx), msg) - return sdk.WrapServiceResult(ctx, res, err) - - default: - return nil, sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "unrecognized %s message type: %T", types.ModuleName, msg) - } - } -} diff --git a/x/auth/vesting/handler_test.go b/x/auth/vesting/handler_test.go deleted file mode 100644 index 6b36ff058343..000000000000 --- a/x/auth/vesting/handler_test.go +++ /dev/null @@ -1,148 +0,0 @@ -package vesting_test - -import ( - "testing" - - "github.com/stretchr/testify/suite" - tmproto "github.com/tendermint/tendermint/proto/tendermint/types" - - "github.com/cosmos/cosmos-sdk/simapp" - sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/cosmos/cosmos-sdk/x/auth/vesting" - "github.com/cosmos/cosmos-sdk/x/auth/vesting/types" -) - -type HandlerTestSuite struct { - suite.Suite - - handler sdk.Handler - app *simapp.SimApp -} - -func (suite *HandlerTestSuite) SetupTest() { - checkTx := false - app := simapp.Setup(checkTx) - - suite.handler = vesting.NewHandler(app.AccountKeeper, app.BankKeeper) - suite.app = app -} - -func (suite *HandlerTestSuite) TestMsgCreateVestingAccount() { - ctx := suite.app.BaseApp.NewContext(false, tmproto.Header{Height: suite.app.LastBlockHeight() + 1}) - - balances := sdk.NewCoins(sdk.NewInt64Coin("test", 1000)) - addr1 := sdk.AccAddress([]byte("addr1_______________")) - addr2 := sdk.AccAddress([]byte("addr2_______________")) - addr3 := sdk.AccAddress([]byte("addr3_______________")) - - acc1 := suite.app.AccountKeeper.NewAccountWithAddress(ctx, addr1) - suite.app.AccountKeeper.SetAccount(ctx, acc1) - suite.Require().NoError(simapp.FundAccount(suite.app.BankKeeper, ctx, addr1, balances)) - - testCases := []struct { - name string - msg *types.MsgCreateVestingAccount - expectErr bool - }{ - { - name: "create delayed vesting account", - msg: types.NewMsgCreateVestingAccount(addr1, addr2, sdk.NewCoins(sdk.NewInt64Coin("test", 100)), ctx.BlockTime().Unix()+10000, true), - expectErr: false, - }, - { - name: "create continuous vesting account", - msg: types.NewMsgCreateVestingAccount(addr1, addr3, sdk.NewCoins(sdk.NewInt64Coin("test", 100)), ctx.BlockTime().Unix()+10000, false), - expectErr: false, - }, - { - name: "continuous vesting account already exists", - msg: types.NewMsgCreateVestingAccount(addr1, addr3, sdk.NewCoins(sdk.NewInt64Coin("test", 100)), ctx.BlockTime().Unix()+10000, false), - expectErr: true, - }, - } - - for _, tc := range testCases { - tc := tc - - suite.Run(tc.name, func() { - res, err := suite.handler(ctx, tc.msg) - if tc.expectErr { - suite.Require().Error(err) - } else { - suite.Require().NoError(err) - suite.Require().NotNil(res) - - toAddr, err := sdk.AccAddressFromBech32(tc.msg.ToAddress) - suite.Require().NoError(err) - accI := suite.app.AccountKeeper.GetAccount(ctx, toAddr) - suite.Require().NotNil(accI) - - if tc.msg.Delayed { - acc, ok := accI.(*types.DelayedVestingAccount) - suite.Require().True(ok) - suite.Require().Equal(tc.msg.Amount, acc.GetVestingCoins(ctx.BlockTime())) - } else { - acc, ok := accI.(*types.ContinuousVestingAccount) - suite.Require().True(ok) - suite.Require().Equal(tc.msg.Amount, acc.GetVestingCoins(ctx.BlockTime())) - } - } - }) - } -} - -func (suite *HandlerTestSuite) TestMsgCreatePeriodicVestingAccount() { - ctx := suite.app.BaseApp.NewContext(false, tmproto.Header{Height: suite.app.LastBlockHeight() + 1}) - - balances := sdk.NewCoins(sdk.NewInt64Coin("test", 1000)) - addr1 := sdk.AccAddress([]byte("addr1_______________")) - addr3 := sdk.AccAddress([]byte("addr3_______________")) - - acc1 := suite.app.AccountKeeper.NewAccountWithAddress(ctx, addr1) - - period := []types.Period{{Length: 5000, Amount: balances}} - suite.app.AccountKeeper.SetAccount(ctx, acc1) - suite.Require().NoError(simapp.FundAccount(suite.app.BankKeeper, ctx, addr1, balances)) - - testCases := []struct { - name string - msg *types.MsgCreatePeriodicVestingAccount - expectErr bool - }{ - { - name: "create periodic vesting account", - msg: types.NewMsgCreatePeriodicVestingAccount(addr1, addr3, 0, period), - expectErr: false, - }, - } - - for _, tc := range testCases { - tc := tc - - suite.Run(tc.name, func() { - res, err := suite.handler(ctx, tc.msg) - if tc.expectErr { - suite.Require().Error(err) - } else { - suite.Require().NoError(err) - suite.Require().NotNil(res) - - toAddr, err := sdk.AccAddressFromBech32(tc.msg.ToAddress) - - suite.Require().NoError(err) - fromAddr, err := sdk.AccAddressFromBech32(tc.msg.FromAddress) - suite.Require().NoError(err) - - accI := suite.app.AccountKeeper.GetAccount(ctx, toAddr) - suite.Require().NotNil(accI) - balance := suite.app.BankKeeper.GetBalance(ctx, fromAddr, "test") - suite.Require().Equal(balance, sdk.NewInt64Coin("test", 0)) - - } - }) - } -} - -func TestHandlerTestSuite(t *testing.T) { - suite.Run(t, new(HandlerTestSuite)) -} From d76fea345fb9af932c0337ff4b042651f088bd49 Mon Sep 17 00:00:00 2001 From: Zaki Manian Date: Tue, 24 Aug 2021 06:11:30 -0700 Subject: [PATCH 28/30] Update CHANGELOG.md Co-authored-by: Amaury <1293565+amaurym@users.noreply.github.com> --- CHANGELOG.md | 1 - 1 file changed, 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 18d55cf49ed6..62fe0bf098f9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -84,7 +84,6 @@ Ref: https://keepachangelog.com/en/1.0.0/ ### Bug Fixes -## [v0.43.0-rc0](https://github.com/cosmos/cosmos-sdk/releases/tag/v0.43.0-rc0) - 2021-06-25 * [\#9651](https://github.com/cosmos/cosmos-sdk/pull/9651) Change inconsistent limit of `0` to `MaxUint64` on InfiniteGasMeter and add GasRemaining func to GasMeter. * [\#9639](https://github.com/cosmos/cosmos-sdk/pull/9639) Check store keys length before accessing them by making sure that `key` is of length `m+1` (for `key[n:m]`) * (types) [\#9627](https://github.com/cosmos/cosmos-sdk/pull/9627) Fix nil pointer panic on `NewBigIntFromInt` From a17c296f1eee99ab1b58d9da5bc60f9499565d1e Mon Sep 17 00:00:00 2001 From: Zaki Manian Date: Tue, 24 Aug 2021 06:11:52 -0700 Subject: [PATCH 29/30] Update CHANGELOG.md Co-authored-by: Amaury <1293565+amaurym@users.noreply.github.com> --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 62fe0bf098f9..718f90318f12 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -97,6 +97,7 @@ Ref: https://keepachangelog.com/en/1.0.0/ + [\#9980](https://github.com/cosmos/cosmos-sdk/pull/9980) Returning the error when the invalid argument is passed to bank query total supply cli. ### State Machine Breaking + * (x/auth)[\#9596](https://github.com/cosmos/cosmos-sdk/pull/9596) Enable creating periodic vesting accounts with a transactions instead of requiring them to be created in genesis. * (x/bank) [\#9611](https://github.com/cosmos/cosmos-sdk/pull/9611) Introduce a new index to act as a reverse index between a denomination and address allowing to query for token holders of a specific denomination. `DenomOwners` is updated to use the new reverse index. From e233f18e0ce0c222e86bb86b3b4319cb462daeee Mon Sep 17 00:00:00 2001 From: Zaki Manian Date: Tue, 24 Aug 2021 07:09:49 -0700 Subject: [PATCH 30/30] Update x/auth/vesting/client/cli/tx.go Co-authored-by: Amaury <1293565+amaurym@users.noreply.github.com> --- x/auth/vesting/client/cli/tx.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x/auth/vesting/client/cli/tx.go b/x/auth/vesting/client/cli/tx.go index e0ec5eff2d7b..28c7e67dec9d 100644 --- a/x/auth/vesting/client/cli/tx.go +++ b/x/auth/vesting/client/cli/tx.go @@ -117,7 +117,7 @@ func NewMsgCreatePeriodicVestingAccountCmd() *cobra.Command { ] } `, - Args: cobra.ExactArgs(3), + Args: cobra.ExactArgs(2), RunE: func(cmd *cobra.Command, args []string) error { clientCtx, err := client.GetClientTxContext(cmd) if err != nil {