Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat!: periodic vesting msg #9596

Merged
merged 33 commits into from
Aug 25, 2021
Merged
Show file tree
Hide file tree
Changes from 9 commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
abd8677
Add a msg for create PeriodicVestingAccount
zmanian Apr 26, 2021
5e65a9c
Address code review comments
zmanian Jun 4, 2021
48098c5
validate periodic vesting messages period length is greater than 0.
zmanian Jun 21, 2021
d0a7a0a
update error message on invalid vesting lenght
zmanian Jun 21, 2021
b4b4d81
error on invalid lengths in json
zmanian Jun 21, 2021
663cc47
update the help message
zmanian Jun 21, 2021
95b4f12
Add support start time to periodic vesting
zmanian Jun 27, 2021
c58b3fd
Merge branch 'zaki-periodic-vesting-msg-alpha' into zaki-upstream-per…
zmanian Jun 28, 2021
57f3014
Add changelog entry
zmanian Jun 28, 2021
bfc95c2
Update x/auth/vesting/client/cli/tx.go
zmanian Jun 28, 2021
f5c45c5
Update x/auth/vesting/client/cli/tx.go
zmanian Jun 28, 2021
548f4da
Add starttime to the vesting input file
zmanian Jul 2, 2021
ce81fc6
Fix tests
zmanian Jul 2, 2021
1830947
Remove the delayed flag
zmanian Jul 2, 2021
48640b9
add json tags
zmanian Jul 2, 2021
334fc1a
Update proto/cosmos/vesting/v1beta1/tx.proto
zmanian Jul 6, 2021
190bf7e
Update x/auth/vesting/types/msgs.go
zmanian Jul 16, 2021
c74c346
Update msg_server.go
zmanian Jul 16, 2021
e9de0e1
Update x/auth/vesting/types/msgs.go
zmanian Jul 16, 2021
873b335
Update x/auth/vesting/types/msgs.go
zmanian Aug 23, 2021
7499718
Add the missing type switch in
zmanian Aug 10, 2021
b7cd77a
Fix the computation of total coins
zmanian Aug 10, 2021
4d43a62
bug! add unit test
zmanian Aug 10, 2021
42f6ca0
move changelog entry
zmanian Aug 23, 2021
7a7fb4c
Add MsgCreatePeriodicVestingAccountResponse
zmanian Aug 23, 2021
954953f
Remove redundant blocked account check
zmanian Aug 23, 2021
6039fd8
Allow period lengths of zero
zmanian Aug 23, 2021
9f978b6
Remove handlers
zmanian Aug 23, 2021
eda233d
Merge branch 'master' of github.com:cosmos/cosmos-sdk into zaki-upstr…
zmanian Aug 23, 2021
d76fea3
Update CHANGELOG.md
zmanian Aug 24, 2021
a17c296
Update CHANGELOG.md
zmanian Aug 24, 2021
e233f18
Update x/auth/vesting/client/cli/tx.go
zmanian Aug 24, 2021
ccdcbd6
Merge branch 'master' into zaki-upstream-periodic-vesting-msg
zmanian Aug 25, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.
zmanian marked this conversation as resolved.
Show resolved Hide resolved
* (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.
Expand Down
145 changes: 83 additions & 62 deletions docs/core/proto-docs.md
Original file line number Diff line number Diff line change
Expand Up @@ -571,12 +571,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)
Expand All @@ -585,6 +579,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)


Expand Down Expand Up @@ -8063,62 +8064,6 @@ Query defines the gRPC upgrade querier service.



<a name="cosmos/vesting/v1beta1/tx.proto"></a>
<p align="right"><a href="#top">Top</a></p>

## cosmos/vesting/v1beta1/tx.proto



<a name="cosmos.vesting.v1beta1.MsgCreateVestingAccount"></a>

### 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) | | |






<a name="cosmos.vesting.v1beta1.MsgCreateVestingAccountResponse"></a>

### MsgCreateVestingAccountResponse
MsgCreateVestingAccountResponse defines the Msg/CreateVestingAccount response type.





<!-- end messages -->

<!-- end enums -->

<!-- end HasExtensions -->


<a name="cosmos.vesting.v1beta1.Msg"></a>

### 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. | |

<!-- end services -->



<a name="cosmos/vesting/v1beta1/vesting.proto"></a>
<p align="right"><a href="#top">Top</a></p>

Expand Down Expand Up @@ -8240,6 +8185,82 @@ still be used for delegating and for governance votes even while locked.



<a name="cosmos/vesting/v1beta1/tx.proto"></a>
<p align="right"><a href="#top">Top</a></p>

## cosmos/vesting/v1beta1/tx.proto



<a name="cosmos.vesting.v1beta1.MsgCreatePeriodicVestingAccount"></a>

### MsgCreatePeriodicVestingAccount
MsgCreateVestingAccount defines a message that enables creating a vesting
account.


| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| `from_address` | [string](#string) | | |
| `to_address` | [string](#string) | | |
| `start_time` | [int64](#int64) | | |
| `vesting_periods` | [Period](#cosmos.vesting.v1beta1.Period) | repeated | |






<a name="cosmos.vesting.v1beta1.MsgCreateVestingAccount"></a>

### 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) | | |






<a name="cosmos.vesting.v1beta1.MsgCreateVestingAccountResponse"></a>

### MsgCreateVestingAccountResponse
MsgCreateVestingAccountResponse defines the Msg/CreateVestingAccount response type.





<!-- end messages -->

<!-- end enums -->

<!-- end HasExtensions -->


<a name="cosmos.vesting.v1beta1.Msg"></a>

### 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) | | |

<!-- end services -->



## Scalar Value Types

| .proto Type | Notes | C++ | Java | Python | Go | C# | PHP | Ruby |
Expand Down
16 changes: 15 additions & 1 deletion proto/cosmos/vesting/v1beta1/tx.proto
Original file line number Diff line number Diff line change
Expand Up @@ -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";

Expand All @@ -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);
zmanian marked this conversation as resolved.
Show resolved Hide resolved
}

// MsgCreateVestingAccount defines a message that enables creating a vesting
Expand All @@ -28,4 +30,16 @@ message MsgCreateVestingAccount {
}

// MsgCreateVestingAccountResponse defines the Msg/CreateVestingAccount response type.
message MsgCreateVestingAccountResponse {}
message MsgCreateVestingAccountResponse {}


// MsgCreateVestingAccount defines a message that enables creating a vesting
// account.
message MsgCreatePeriodicVestingAccount {
zmanian marked this conversation as resolved.
Show resolved Hide resolved
option (gogoproto.equal) = false;

string from_address = 1 [(gogoproto.moretags) = "yaml:\"from_address\""];
string to_address = 2 [(gogoproto.moretags) = "yaml:\"to_address\""];
int64 start_time = 3 [(gogoproto.moretags) = "yaml:\"start_time\""];
repeated Period vesting_periods = 4 [(gogoproto.nullable) = false];
}
91 changes: 91 additions & 0 deletions x/auth/vesting/client/cli/tx.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
package cli

import (
"encoding/json"
"fmt"
"io/ioutil"
"strconv"

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

txCmd.AddCommand(
NewMsgCreateVestingAccountCmd(),
NewMsgCreatePeriodicVestingAccountCmd(),
)

return txCmd
Expand Down Expand Up @@ -79,3 +83,90 @@ timestamp.`,

return cmd
}

type InputPeriod struct {
Coins string `json:"coins"`
Length int64 `json:"length_seconds"`
}

// NewMsgCreateVestingAccountCmd returns a CLI command handler for creating a
// MsgCreateVestingAccount transaction.
func NewMsgCreatePeriodicVestingAccountCmd() *cobra.Command {
cmd := &cobra.Command{
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:

An array of coin strings and unix epoch times for coins to vest

[
{
"coins": "10test",
"length_seconds":2592000 //30 days
},
{
"coins": "10test",
"length_seconds":2592000 //30 days
},
]
zmanian marked this conversation as resolved.
Show resolved Hide resolved
`,
Args: cobra.ExactArgs(3),
zmanian marked this conversation as resolved.
Show resolved Hide resolved
RunE: func(cmd *cobra.Command, args []string) error {
clientCtx, err := client.GetClientTxContext(cmd)
if err != nil {
return err
}

startTime, err := strconv.ParseInt(args[0], 10, 64)

if err != nil {
zmanian marked this conversation as resolved.
Show resolved Hide resolved
return err
}
toAddr, err := sdk.AccAddressFromBech32(args[1])
if err != nil {
return err
}

contents, err := ioutil.ReadFile(args[2])
if err != nil {
return err
}

var inputPeriods []InputPeriod

err = json.Unmarshal(contents, &inputPeriods)
if err != nil {
return err
}

var periods []types.Period

for i, p := range inputPeriods {

zmanian marked this conversation as resolved.
Show resolved Hide resolved
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)
zmanian marked this conversation as resolved.
Show resolved Hide resolved
}
period := types.Period{Length: p.Length, Amount: amount}
periods = append(periods, period)
}

msg := types.NewMsgCreatePeriodicVestingAccount(clientCtx.GetFromAddress(), toAddr, startTime, 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")
zmanian marked this conversation as resolved.
Show resolved Hide resolved
flags.AddTxFlagsToCmd(cmd)

return cmd
}
46 changes: 46 additions & 0 deletions x/auth/vesting/handler_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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))
zmanian marked this conversation as resolved.
Show resolved Hide resolved

testCases := []struct {
name string
msg *types.MsgCreatePeriodicVestingAccount
expectErr bool
}{
{
name: "continuous vesting account already exists",
msg: types.NewMsgCreatePeriodicVestingAccount(addr1, addr3, period),
expectErr: true,
amaury1093 marked this conversation as resolved.
Show resolved Hide resolved
},
}

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))
}