Skip to content

Commit a061de6

Browse files
zmanianyun-yeo
authored andcommitted
feat!: periodic vesting msg (cosmos#9596)
Closes: cosmos#9595 Enables creating a periodic vesting account on a running chain. I have... - [x] included the correct [type prefix](https://github.com/commitizen/conventional-commit-types/blob/v3.0.0/index.json) in the PR title - [x] added `!` to the type prefix if API or client breaking change - [x] targeted the correct branch (see [PR Targeting](https://github.com/cosmos/cosmos-sdk/blob/master/CONTRIBUTING.md#pr-targeting)) - [x] provided a link to the relevant issue or specification - [x] followed the guidelines for [building modules](https://github.com/cosmos/cosmos-sdk/blob/master/docs/building-modules) - [x] included the necessary unit and integration [tests](https://github.com/cosmos/cosmos-sdk/blob/master/CONTRIBUTING.md#testing) - [x] added a changelog entry to `CHANGELOG.md` - [ ] included comments for [documenting Go code](https://blog.golang.org/godoc) - [ ] updated the relevant documentation or specification - [ ] reviewed "Files changed" and left comments if necessary - [ ] confirmed all CI checks have passed *All items are required. Please add a note if the item is not applicable and please add your handle next to the items reviewed if you only reviewed selected items.* I have... - [ ] confirmed the correct [type prefix](https://github.com/commitizen/conventional-commit-types/blob/v3.0.0/index.json) in the PR title - [ ] confirmed `!` in the type prefix if API or client breaking change - [ ] confirmed all author checklist items have been addressed - [ ] reviewed state machine logic - [ ] reviewed API design and naming - [ ] reviewed documentation is accurate - [ ] reviewed tests and test coverage - [ ] manually tested (if applicable) chore: Add proto comments for MsgCreatePeriodicVestingAccountResponse (cosmos#10007) <!-- The default pull request template is for types feat, fix, or refactor. For other templates, add one of the following parameters to the url: - template=docs.md - template=other.md --> We merged cosmos#9596, but we forgot to add proto comments for one message. Then, proto lint CI fails on unrelated PRs, e.g. https://github.com/cosmos/cosmos-sdk/pull/9759/checks?check_run_id=3421076482#step:4:24. This fixes it. Also related to cosmos#9978 <!-- Add a description of the changes that this PR introduces and the files that are the most critical to review. --> --- *All items are required. Please add a note to the item if the item is not applicable and please add links to any relevant follow up issues.* I have... - [x] included the correct [type prefix](https://github.com/commitizen/conventional-commit-types/blob/v3.0.0/index.json) in the PR title - [ ] added `!` to the type prefix if API or client breaking change - [ ] targeted the correct branch (see [PR Targeting](https://github.com/cosmos/cosmos-sdk/blob/master/CONTRIBUTING.md#pr-targeting)) - [ ] provided a link to the relevant issue or specification - [ ] followed the guidelines for [building modules](https://github.com/cosmos/cosmos-sdk/blob/master/docs/building-modules) - [ ] included the necessary unit and integration [tests](https://github.com/cosmos/cosmos-sdk/blob/master/CONTRIBUTING.md#testing) - [ ] added a changelog entry to `CHANGELOG.md` - [x] included comments for [documenting Go code](https://blog.golang.org/godoc) - [ ] updated the relevant documentation or specification - [x] reviewed "Files changed" and left comments if necessary - [x] confirmed all CI checks have passed *All items are required. Please add a note if the item is not applicable and please add your handle next to the items reviewed if you only reviewed selected items.* I have... - [ ] confirmed the correct [type prefix](https://github.com/commitizen/conventional-commit-types/blob/v3.0.0/index.json) in the PR title - [ ] confirmed `!` in the type prefix if API or client breaking change - [ ] confirmed all author checklist items have been addressed - [ ] reviewed state machine logic - [ ] reviewed API design and naming - [ ] reviewed documentation is accurate - [ ] reviewed tests and test coverage - [ ] manually tested (if applicable)
1 parent eca20f0 commit a061de6

File tree

8 files changed

+862
-90
lines changed

8 files changed

+862
-90
lines changed

CHANGELOG.md

+4
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,10 @@ Ref: https://keepachangelog.com/en/1.0.0/
3737

3838
## [Unreleased]
3939

40+
### State Machine Breaking
41+
42+
* (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.
43+
4044
## [v0.45.4](https://github.com/cosmos/cosmos-sdk/releases/tag/v0.45.4) - 2022-04-25
4145

4246
### Bug Fixes

docs/core/proto-docs.md

+95-62
Original file line numberDiff line numberDiff line change
@@ -579,12 +579,6 @@
579579

580580
- [Query](#cosmos.upgrade.v1beta1.Query)
581581

582-
- [cosmos/vesting/v1beta1/tx.proto](#cosmos/vesting/v1beta1/tx.proto)
583-
- [MsgCreateVestingAccount](#cosmos.vesting.v1beta1.MsgCreateVestingAccount)
584-
- [MsgCreateVestingAccountResponse](#cosmos.vesting.v1beta1.MsgCreateVestingAccountResponse)
585-
586-
- [Msg](#cosmos.vesting.v1beta1.Msg)
587-
588582
- [cosmos/vesting/v1beta1/vesting.proto](#cosmos/vesting/v1beta1/vesting.proto)
589583
- [BaseVestingAccount](#cosmos.vesting.v1beta1.BaseVestingAccount)
590584
- [ContinuousVestingAccount](#cosmos.vesting.v1beta1.ContinuousVestingAccount)
@@ -593,6 +587,14 @@
593587
- [PeriodicVestingAccount](#cosmos.vesting.v1beta1.PeriodicVestingAccount)
594588
- [PermanentLockedAccount](#cosmos.vesting.v1beta1.PermanentLockedAccount)
595589

590+
- [cosmos/vesting/v1beta1/tx.proto](#cosmos/vesting/v1beta1/tx.proto)
591+
- [MsgCreatePeriodicVestingAccount](#cosmos.vesting.v1beta1.MsgCreatePeriodicVestingAccount)
592+
- [MsgCreatePeriodicVestingAccountResponse](#cosmos.vesting.v1beta1.MsgCreatePeriodicVestingAccountResponse)
593+
- [MsgCreateVestingAccount](#cosmos.vesting.v1beta1.MsgCreateVestingAccount)
594+
- [MsgCreateVestingAccountResponse](#cosmos.vesting.v1beta1.MsgCreateVestingAccountResponse)
595+
596+
- [Msg](#cosmos.vesting.v1beta1.Msg)
597+
596598
- [Scalar Value Types](#scalar-value-types)
597599

598600

@@ -8281,62 +8283,6 @@ Since: cosmos-sdk 0.43 | GET|/cosmos/upgrade/v1beta1/module_versions|
82818283

82828284

82838285

8284-
<a name="cosmos/vesting/v1beta1/tx.proto"></a>
8285-
<p align="right"><a href="#top">Top</a></p>
8286-
8287-
## cosmos/vesting/v1beta1/tx.proto
8288-
8289-
8290-
8291-
<a name="cosmos.vesting.v1beta1.MsgCreateVestingAccount"></a>
8292-
8293-
### MsgCreateVestingAccount
8294-
MsgCreateVestingAccount defines a message that enables creating a vesting
8295-
account.
8296-
8297-
8298-
| Field | Type | Label | Description |
8299-
| ----- | ---- | ----- | ----------- |
8300-
| `from_address` | [string](#string) | | |
8301-
| `to_address` | [string](#string) | | |
8302-
| `amount` | [cosmos.base.v1beta1.Coin](#cosmos.base.v1beta1.Coin) | repeated | |
8303-
| `end_time` | [int64](#int64) | | |
8304-
| `delayed` | [bool](#bool) | | |
8305-
8306-
8307-
8308-
8309-
8310-
8311-
<a name="cosmos.vesting.v1beta1.MsgCreateVestingAccountResponse"></a>
8312-
8313-
### MsgCreateVestingAccountResponse
8314-
MsgCreateVestingAccountResponse defines the Msg/CreateVestingAccount response type.
8315-
8316-
8317-
8318-
8319-
8320-
<!-- end messages -->
8321-
8322-
<!-- end enums -->
8323-
8324-
<!-- end HasExtensions -->
8325-
8326-
8327-
<a name="cosmos.vesting.v1beta1.Msg"></a>
8328-
8329-
### Msg
8330-
Msg defines the bank Msg service.
8331-
8332-
| Method Name | Request Type | Response Type | Description | HTTP Verb | Endpoint |
8333-
| ----------- | ------------ | ------------- | ------------| ------- | -------- |
8334-
| `CreateVestingAccount` | [MsgCreateVestingAccount](#cosmos.vesting.v1beta1.MsgCreateVestingAccount) | [MsgCreateVestingAccountResponse](#cosmos.vesting.v1beta1.MsgCreateVestingAccountResponse) | CreateVestingAccount defines a method that enables creating a vesting account. | |
8335-
8336-
<!-- end services -->
8337-
8338-
8339-
83408286
<a name="cosmos/vesting/v1beta1/vesting.proto"></a>
83418287
<p align="right"><a href="#top">Top</a></p>
83428288

@@ -8460,6 +8406,93 @@ Since: cosmos-sdk 0.43
84608406

84618407

84628408

8409+
<a name="cosmos/vesting/v1beta1/tx.proto"></a>
8410+
<p align="right"><a href="#top">Top</a></p>
8411+
8412+
## cosmos/vesting/v1beta1/tx.proto
8413+
8414+
8415+
8416+
<a name="cosmos.vesting.v1beta1.MsgCreatePeriodicVestingAccount"></a>
8417+
8418+
### MsgCreatePeriodicVestingAccount
8419+
MsgCreateVestingAccount defines a message that enables creating a vesting
8420+
account.
8421+
8422+
8423+
| Field | Type | Label | Description |
8424+
| ----- | ---- | ----- | ----------- |
8425+
| `from_address` | [string](#string) | | |
8426+
| `to_address` | [string](#string) | | |
8427+
| `start_time` | [int64](#int64) | | |
8428+
| `vesting_periods` | [Period](#cosmos.vesting.v1beta1.Period) | repeated | |
8429+
8430+
8431+
8432+
8433+
8434+
8435+
<a name="cosmos.vesting.v1beta1.MsgCreatePeriodicVestingAccountResponse"></a>
8436+
8437+
### MsgCreatePeriodicVestingAccountResponse
8438+
MsgCreateVestingAccountResponse defines the Msg/CreatePeriodicVestingAccount
8439+
response type.
8440+
8441+
8442+
8443+
8444+
8445+
8446+
<a name="cosmos.vesting.v1beta1.MsgCreateVestingAccount"></a>
8447+
8448+
### MsgCreateVestingAccount
8449+
MsgCreateVestingAccount defines a message that enables creating a vesting
8450+
account.
8451+
8452+
8453+
| Field | Type | Label | Description |
8454+
| ----- | ---- | ----- | ----------- |
8455+
| `from_address` | [string](#string) | | |
8456+
| `to_address` | [string](#string) | | |
8457+
| `amount` | [cosmos.base.v1beta1.Coin](#cosmos.base.v1beta1.Coin) | repeated | |
8458+
| `end_time` | [int64](#int64) | | |
8459+
| `delayed` | [bool](#bool) | | |
8460+
8461+
8462+
8463+
8464+
8465+
8466+
<a name="cosmos.vesting.v1beta1.MsgCreateVestingAccountResponse"></a>
8467+
8468+
### MsgCreateVestingAccountResponse
8469+
MsgCreateVestingAccountResponse defines the Msg/CreateVestingAccount response type.
8470+
8471+
8472+
8473+
8474+
8475+
<!-- end messages -->
8476+
8477+
<!-- end enums -->
8478+
8479+
<!-- end HasExtensions -->
8480+
8481+
8482+
<a name="cosmos.vesting.v1beta1.Msg"></a>
8483+
8484+
### Msg
8485+
Msg defines the bank Msg service.
8486+
8487+
| Method Name | Request Type | Response Type | Description | HTTP Verb | Endpoint |
8488+
| ----------- | ------------ | ------------- | ------------| ------- | -------- |
8489+
| `CreateVestingAccount` | [MsgCreateVestingAccount](#cosmos.vesting.v1beta1.MsgCreateVestingAccount) | [MsgCreateVestingAccountResponse](#cosmos.vesting.v1beta1.MsgCreateVestingAccountResponse) | CreateVestingAccount defines a method that enables creating a vesting account. | |
8490+
| `CreatePeriodicVestingAccount` | [MsgCreatePeriodicVestingAccount](#cosmos.vesting.v1beta1.MsgCreatePeriodicVestingAccount) | [MsgCreatePeriodicVestingAccountResponse](#cosmos.vesting.v1beta1.MsgCreatePeriodicVestingAccountResponse) | CreatePeriodicVestingAccount defines a method that enables creating a periodic vesting account. | |
8491+
8492+
<!-- end services -->
8493+
8494+
8495+
84638496
## Scalar Value Types
84648497

84658498
| .proto Type | Notes | C++ | Java | Python | Go | C# | PHP | Ruby |

proto/cosmos/vesting/v1beta1/tx.proto

+21-1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package cosmos.vesting.v1beta1;
33

44
import "gogoproto/gogo.proto";
55
import "cosmos/base/v1beta1/coin.proto";
6+
import "cosmos/vesting/v1beta1/vesting.proto";
67

78
option go_package = "github.com/cosmos/cosmos-sdk/x/auth/vesting/types";
89

@@ -11,6 +12,9 @@ service Msg {
1112
// CreateVestingAccount defines a method that enables creating a vesting
1213
// account.
1314
rpc CreateVestingAccount(MsgCreateVestingAccount) returns (MsgCreateVestingAccountResponse);
15+
// CreatePeriodicVestingAccount defines a method that enables creating a
16+
// periodic vesting account.
17+
rpc CreatePeriodicVestingAccount(MsgCreatePeriodicVestingAccount) returns (MsgCreatePeriodicVestingAccountResponse);
1418
}
1519

1620
// MsgCreateVestingAccount defines a message that enables creating a vesting
@@ -28,4 +32,20 @@ message MsgCreateVestingAccount {
2832
}
2933

3034
// MsgCreateVestingAccountResponse defines the Msg/CreateVestingAccount response type.
31-
message MsgCreateVestingAccountResponse {}
35+
message MsgCreateVestingAccountResponse {}
36+
37+
38+
// MsgCreateVestingAccount defines a message that enables creating a vesting
39+
// account.
40+
message MsgCreatePeriodicVestingAccount {
41+
option (gogoproto.equal) = false;
42+
43+
string from_address = 1 [(gogoproto.moretags) = "yaml:\"from_address\""];
44+
string to_address = 2 [(gogoproto.moretags) = "yaml:\"to_address\""];
45+
int64 start_time = 3 [(gogoproto.moretags) = "yaml:\"start_time\""];
46+
repeated Period vesting_periods = 4 [(gogoproto.nullable) = false];
47+
}
48+
49+
// MsgCreateVestingAccountResponse defines the Msg/CreatePeriodicVestingAccount
50+
// response type.
51+
message MsgCreatePeriodicVestingAccountResponse {}

x/auth/vesting/client/cli/tx.go

+91
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
package cli
22

33
import (
4+
"encoding/json"
5+
"fmt"
6+
"io/ioutil"
47
"strconv"
58

69
"github.com/spf13/cobra"
@@ -29,6 +32,7 @@ func GetTxCmd() *cobra.Command {
2932

3033
txCmd.AddCommand(
3134
NewMsgCreateVestingAccountCmd(),
35+
NewMsgCreatePeriodicVestingAccountCmd(),
3236
)
3337

3438
return txCmd
@@ -79,3 +83,90 @@ timestamp.`,
7983

8084
return cmd
8185
}
86+
87+
type VestingData struct {
88+
StartTime int64 `json:"start_time"`
89+
Periods []InputPeriod `json:"periods"`
90+
}
91+
92+
type InputPeriod struct {
93+
Coins string `json:"coins"`
94+
Length int64 `json:"length_seconds"`
95+
}
96+
97+
// NewMsgCreatePeriodicVestingAccountCmd returns a CLI command handler for creating a
98+
// MsgCreatePeriodicVestingAccountCmd transaction.
99+
func NewMsgCreatePeriodicVestingAccountCmd() *cobra.Command {
100+
cmd := &cobra.Command{
101+
Use: "create-periodic-vesting-account [to_address] [periods_json_file]",
102+
Short: "Create a new vesting account funded with an allocation of tokens.",
103+
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.
104+
Where periods.json contains:
105+
106+
An array of coin strings and unix epoch times for coins to vest
107+
{ "start_time": 1625204910,
108+
"period":[
109+
{
110+
"coins": "10test",
111+
"length_seconds":2592000 //30 days
112+
},
113+
{
114+
"coins": "10test",
115+
"length_seconds":2592000 //30 days
116+
},
117+
]
118+
}
119+
`,
120+
Args: cobra.ExactArgs(2),
121+
RunE: func(cmd *cobra.Command, args []string) error {
122+
clientCtx, err := client.GetClientTxContext(cmd)
123+
if err != nil {
124+
return err
125+
}
126+
127+
toAddr, err := sdk.AccAddressFromBech32(args[0])
128+
if err != nil {
129+
return err
130+
}
131+
132+
contents, err := ioutil.ReadFile(args[1])
133+
if err != nil {
134+
return err
135+
}
136+
137+
var vestingData VestingData
138+
139+
err = json.Unmarshal(contents, &vestingData)
140+
if err != nil {
141+
return err
142+
}
143+
144+
var periods []types.Period
145+
146+
for i, p := range vestingData.Periods {
147+
148+
amount, err := sdk.ParseCoinsNormalized(p.Coins)
149+
if err != nil {
150+
return err
151+
}
152+
153+
if p.Length < 0 {
154+
return fmt.Errorf("invalid period length of %d in period %d, length must be greater than 0", p.Length, i)
155+
}
156+
period := types.Period{Length: p.Length, Amount: amount}
157+
periods = append(periods, period)
158+
}
159+
160+
msg := types.NewMsgCreatePeriodicVestingAccount(clientCtx.GetFromAddress(), toAddr, vestingData.StartTime, periods)
161+
if err := msg.ValidateBasic(); err != nil {
162+
return err
163+
}
164+
165+
return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msg)
166+
},
167+
}
168+
169+
flags.AddTxFlagsToCmd(cmd)
170+
171+
return cmd
172+
}

x/auth/vesting/handler.go

+4
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,10 @@ func NewHandler(ak keeper.AccountKeeper, bk types.BankKeeper) sdk.Handler {
1919
res, err := msgServer.CreateVestingAccount(sdk.WrapSDKContext(ctx), msg)
2020
return sdk.WrapServiceResult(ctx, res, err)
2121

22+
case *types.MsgCreatePeriodicVestingAccount:
23+
res, err := msgServer.CreatePeriodicVestingAccount(sdk.WrapSDKContext(ctx), msg)
24+
return sdk.WrapServiceResult(ctx, res, err)
25+
2226
default:
2327
return nil, sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "unrecognized %s message type: %T", types.ModuleName, msg)
2428
}

0 commit comments

Comments
 (0)