Skip to content

Commit 5d01af4

Browse files
zmaniandongsam
authored andcommitted
feat: periodic vesting msg, cherry-pick 147d798 cosmos#9596
1 parent 47933d0 commit 5d01af4

File tree

9 files changed

+898
-90
lines changed

9 files changed

+898
-90
lines changed

docs/core/proto-docs.md

+97-62
Original file line numberDiff line numberDiff line change
@@ -571,12 +571,6 @@
571571

572572
- [Query](#cosmos.upgrade.v1beta1.Query)
573573

574-
- [cosmos/vesting/v1beta1/tx.proto](#cosmos/vesting/v1beta1/tx.proto)
575-
- [MsgCreateVestingAccount](#cosmos.vesting.v1beta1.MsgCreateVestingAccount)
576-
- [MsgCreateVestingAccountResponse](#cosmos.vesting.v1beta1.MsgCreateVestingAccountResponse)
577-
578-
- [Msg](#cosmos.vesting.v1beta1.Msg)
579-
580574
- [cosmos/vesting/v1beta1/vesting.proto](#cosmos/vesting/v1beta1/vesting.proto)
581575
- [BaseVestingAccount](#cosmos.vesting.v1beta1.BaseVestingAccount)
582576
- [ContinuousVestingAccount](#cosmos.vesting.v1beta1.ContinuousVestingAccount)
@@ -585,6 +579,14 @@
585579
- [PeriodicVestingAccount](#cosmos.vesting.v1beta1.PeriodicVestingAccount)
586580
- [PermanentLockedAccount](#cosmos.vesting.v1beta1.PermanentLockedAccount)
587581

582+
- [cosmos/vesting/v1beta1/tx.proto](#cosmos/vesting/v1beta1/tx.proto)
583+
- [MsgCreatePeriodicVestingAccount](#cosmos.vesting.v1beta1.MsgCreatePeriodicVestingAccount)
584+
- [MsgCreatePeriodicVestingAccountResponse](#cosmos.vesting.v1beta1.MsgCreatePeriodicVestingAccountResponse)
585+
- [MsgCreateVestingAccount](#cosmos.vesting.v1beta1.MsgCreateVestingAccount)
586+
- [MsgCreateVestingAccountResponse](#cosmos.vesting.v1beta1.MsgCreateVestingAccountResponse)
587+
588+
- [Msg](#cosmos.vesting.v1beta1.Msg)
589+
588590
- [Scalar Value Types](#scalar-value-types)
589591

590592

@@ -1268,6 +1270,9 @@ tags are stringified and the log is JSON decoded.
12681270
| `gas_used` | [int64](#int64) | | Amount of gas consumed by transaction. |
12691271
| `tx` | [google.protobuf.Any](#google.protobuf.Any) | | The request transaction bytes. |
12701272
| `timestamp` | [string](#string) | | Time of the previous block. For heights > 1, it's the weighted median of the timestamps of the valid votes in the block.LastCommit. For height == 1, it's genesis time. |
1273+
| `events` | [tendermint.abci.Event](#tendermint.abci.Event) | repeated | Events defines all the events emitted by processing a transaction. Note, these events include those emitted by processing all the messages and those emitted from the ante handler. Whereas Logs contains the events, with additional metadata, emitted only by processing the messages.
1274+
1275+
Since: cosmos-sdk 0.42.11, 0.44.5, 0.45 |
12711276

12721277

12731278

@@ -8106,62 +8111,6 @@ Since: cosmos-sdk 0.43 | GET|/cosmos/upgrade/v1beta1/module_versions|
81068111

81078112

81088113

8109-
<a name="cosmos/vesting/v1beta1/tx.proto"></a>
8110-
<p align="right"><a href="#top">Top</a></p>
8111-
8112-
## cosmos/vesting/v1beta1/tx.proto
8113-
8114-
8115-
8116-
<a name="cosmos.vesting.v1beta1.MsgCreateVestingAccount"></a>
8117-
8118-
### MsgCreateVestingAccount
8119-
MsgCreateVestingAccount defines a message that enables creating a vesting
8120-
account.
8121-
8122-
8123-
| Field | Type | Label | Description |
8124-
| ----- | ---- | ----- | ----------- |
8125-
| `from_address` | [string](#string) | | |
8126-
| `to_address` | [string](#string) | | |
8127-
| `amount` | [cosmos.base.v1beta1.Coin](#cosmos.base.v1beta1.Coin) | repeated | |
8128-
| `end_time` | [int64](#int64) | | |
8129-
| `delayed` | [bool](#bool) | | |
8130-
8131-
8132-
8133-
8134-
8135-
8136-
<a name="cosmos.vesting.v1beta1.MsgCreateVestingAccountResponse"></a>
8137-
8138-
### MsgCreateVestingAccountResponse
8139-
MsgCreateVestingAccountResponse defines the Msg/CreateVestingAccount response type.
8140-
8141-
8142-
8143-
8144-
8145-
<!-- end messages -->
8146-
8147-
<!-- end enums -->
8148-
8149-
<!-- end HasExtensions -->
8150-
8151-
8152-
<a name="cosmos.vesting.v1beta1.Msg"></a>
8153-
8154-
### Msg
8155-
Msg defines the bank Msg service.
8156-
8157-
| Method Name | Request Type | Response Type | Description | HTTP Verb | Endpoint |
8158-
| ----------- | ------------ | ------------- | ------------| ------- | -------- |
8159-
| `CreateVestingAccount` | [MsgCreateVestingAccount](#cosmos.vesting.v1beta1.MsgCreateVestingAccount) | [MsgCreateVestingAccountResponse](#cosmos.vesting.v1beta1.MsgCreateVestingAccountResponse) | CreateVestingAccount defines a method that enables creating a vesting account. | |
8160-
8161-
<!-- end services -->
8162-
8163-
8164-
81658114
<a name="cosmos/vesting/v1beta1/vesting.proto"></a>
81668115
<p align="right"><a href="#top">Top</a></p>
81678116

@@ -8285,6 +8234,92 @@ Since: cosmos-sdk 0.43
82858234

82868235

82878236

8237+
<a name="cosmos/vesting/v1beta1/tx.proto"></a>
8238+
<p align="right"><a href="#top">Top</a></p>
8239+
8240+
## cosmos/vesting/v1beta1/tx.proto
8241+
8242+
8243+
8244+
<a name="cosmos.vesting.v1beta1.MsgCreatePeriodicVestingAccount"></a>
8245+
8246+
### MsgCreatePeriodicVestingAccount
8247+
MsgCreateVestingAccount defines a message that enables creating a vesting
8248+
account.
8249+
8250+
8251+
| Field | Type | Label | Description |
8252+
| ----- | ---- | ----- | ----------- |
8253+
| `from_address` | [string](#string) | | |
8254+
| `to_address` | [string](#string) | | |
8255+
| `start_time` | [int64](#int64) | | |
8256+
| `vesting_periods` | [Period](#cosmos.vesting.v1beta1.Period) | repeated | |
8257+
8258+
8259+
8260+
8261+
8262+
8263+
<a name="cosmos.vesting.v1beta1.MsgCreatePeriodicVestingAccountResponse"></a>
8264+
8265+
### MsgCreatePeriodicVestingAccountResponse
8266+
MsgCreatePeriodicVestingAccountResponse defines the Msg/CreatePeriodicVestingAccount response type.
8267+
8268+
8269+
8270+
8271+
8272+
8273+
<a name="cosmos.vesting.v1beta1.MsgCreateVestingAccount"></a>
8274+
8275+
### MsgCreateVestingAccount
8276+
MsgCreateVestingAccount defines a message that enables creating a vesting
8277+
account.
8278+
8279+
8280+
| Field | Type | Label | Description |
8281+
| ----- | ---- | ----- | ----------- |
8282+
| `from_address` | [string](#string) | | |
8283+
| `to_address` | [string](#string) | | |
8284+
| `amount` | [cosmos.base.v1beta1.Coin](#cosmos.base.v1beta1.Coin) | repeated | |
8285+
| `end_time` | [int64](#int64) | | |
8286+
| `delayed` | [bool](#bool) | | |
8287+
8288+
8289+
8290+
8291+
8292+
8293+
<a name="cosmos.vesting.v1beta1.MsgCreateVestingAccountResponse"></a>
8294+
8295+
### MsgCreateVestingAccountResponse
8296+
MsgCreateVestingAccountResponse defines the Msg/CreateVestingAccount response type.
8297+
8298+
8299+
8300+
8301+
8302+
<!-- end messages -->
8303+
8304+
<!-- end enums -->
8305+
8306+
<!-- end HasExtensions -->
8307+
8308+
8309+
<a name="cosmos.vesting.v1beta1.Msg"></a>
8310+
8311+
### Msg
8312+
Msg defines the bank Msg service.
8313+
8314+
| Method Name | Request Type | Response Type | Description | HTTP Verb | Endpoint |
8315+
| ----------- | ------------ | ------------- | ------------| ------- | -------- |
8316+
| `CreateVestingAccount` | [MsgCreateVestingAccount](#cosmos.vesting.v1beta1.MsgCreateVestingAccount) | [MsgCreateVestingAccountResponse](#cosmos.vesting.v1beta1.MsgCreateVestingAccountResponse) | CreateVestingAccount defines a method that enables creating a vesting account. | |
8317+
| `CreatePeriodicVestingAccount` | [MsgCreatePeriodicVestingAccount](#cosmos.vesting.v1beta1.MsgCreatePeriodicVestingAccount) | [MsgCreatePeriodicVestingAccountResponse](#cosmos.vesting.v1beta1.MsgCreatePeriodicVestingAccountResponse) | CreatePeriodicVestingAccount defines a method that enables creating a periodic vesting account. | |
8318+
8319+
<!-- end services -->
8320+
8321+
8322+
82888323
## Scalar Value Types
82898324

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

proto/cosmos/vesting/v1beta1/tx.proto

+19-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,18 @@ message MsgCreateVestingAccount {
2832
}
2933

3034
// MsgCreateVestingAccountResponse defines the Msg/CreateVestingAccount response type.
31-
message MsgCreateVestingAccountResponse {}
35+
message MsgCreateVestingAccountResponse {}
36+
37+
// MsgCreateVestingAccount defines a message that enables creating a vesting
38+
// account.
39+
message MsgCreatePeriodicVestingAccount {
40+
option (gogoproto.equal) = false;
41+
42+
string from_address = 1 [(gogoproto.moretags) = "yaml:\"from_address\""];
43+
string to_address = 2 [(gogoproto.moretags) = "yaml:\"to_address\""];
44+
int64 start_time = 3 [(gogoproto.moretags) = "yaml:\"start_time\""];
45+
repeated Period vesting_periods = 4 [(gogoproto.nullable) = false];
46+
}
47+
48+
// MsgCreatePeriodicVestingAccountResponse defines the Msg/CreatePeriodicVestingAccount response type.
49+
message MsgCreatePeriodicVestingAccountResponse {}
+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
{
2+
"start_time": 1645403872,
3+
"period":
4+
[
5+
{
6+
"coins": "1000000stake",
7+
"length_seconds": 60000
8+
},
9+
{
10+
"coins": "1000000stake",
11+
"length_seconds": 60000
12+
},
13+
{
14+
"coins": "1000000stake",
15+
"length_seconds": 60000
16+
},
17+
{
18+
"coins": "1000000stake",
19+
"length_seconds": 60000
20+
}
21+
]
22+
}
+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
{
2+
"start_time": 1645403872,
3+
"period":
4+
[
5+
{
6+
"coins": "1000000stake",
7+
"length_seconds": 60000
8+
},
9+
{
10+
"coins": "1000000stake",
11+
"length_seconds": 60000
12+
},
13+
{
14+
"coins": "1000000stake",
15+
"length_seconds": 60000
16+
},
17+
{
18+
"coins": "1000000stake",
19+
"length_seconds": 60000
20+
}
21+
]
22+
}

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+
"periods":[
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/client/cli/tx_test.go

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
package cli

0 commit comments

Comments
 (0)