Skip to content

Commit 117493b

Browse files
authored
Merge pull request #634 from axone-protocol/refactor/update-vesting
🔃 Update vesting module to cosmos-sdk v0.50.6
2 parents 4fd603e + caca9a7 commit 117493b

31 files changed

+1836
-517
lines changed

.github/workflows/test.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ jobs:
5757
env_vars: OS,GOLANG
5858
fail_ci_if_error: false
5959
verbose: true
60+
token: ${{ secrets.CODECOV_TOKEN }}
6061

6162
test-blockchain:
6263
runs-on: ubuntu-22.04

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -319,7 +319,7 @@ doc: doc-proto doc-command doc-predicate ## Generate all the documentation
319319
doc-proto: proto-gen ## Generate the documentation from the Protobuf files
320320
@echo "${COLOR_CYAN} 📝 Generating doc from Protobuf files${COLOR_RESET}"
321321
@$(DOCKER_PROTO_RUN) sh ./scripts/protocgen-doc.sh
322-
@for MODULE in $(shell find proto -name '*.proto' -print0 | xargs -0 -n1 dirname | sort | uniq | xargs dirname) ; do \
322+
@for MODULE in $(shell find proto -name '*.proto' -maxdepth 3 -print0 | xargs -0 -n1 dirname | sort | uniq | xargs dirname) ; do \
323323
echo "${COLOR_CYAN} 📖 Generate documentation for $${MODULE} module${COLOR_RESET}" ; \
324324
DEFAULT_DATASOURCE="./docs/proto/templates/default.yaml" ; \
325325
MODULE_DATASOURCE="merge:./$${MODULE}/docs.yaml|$${DEFAULT_DATASOURCE}" ; \

cmd/axoned/cmd/genaccount.go

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
package cmd
2+
3+
import (
4+
"bufio"
5+
"fmt"
6+
7+
"github.com/spf13/cobra"
8+
9+
address "cosmossdk.io/core/address"
10+
11+
"github.com/cosmos/cosmos-sdk/client"
12+
"github.com/cosmos/cosmos-sdk/client/flags"
13+
"github.com/cosmos/cosmos-sdk/crypto/keyring"
14+
"github.com/cosmos/cosmos-sdk/server"
15+
sdk "github.com/cosmos/cosmos-sdk/types"
16+
17+
vestingtypes "github.com/axone-protocol/axoned/v8/x/vesting/types"
18+
)
19+
20+
const (
21+
flagVestingStart = "vesting-start-time"
22+
flagVestingCliff = "vesting-cliff-time"
23+
flagVestingEnd = "vesting-end-time"
24+
flagVestingAmt = "vesting-amount"
25+
flagAppendMode = "append"
26+
flagModuleName = "module-name"
27+
)
28+
29+
// AddGenesisAccountCmd returns add-genesis-account cobra Command.
30+
// This command is provided as a default, applications are expected to provide their own command if custom genesis accounts are needed.
31+
//
32+
//nolint:funlen,nestif
33+
func AddGenesisAccountCmd(defaultNodeHome string, addressCodec address.Codec) *cobra.Command {
34+
cmd := &cobra.Command{
35+
Use: "add-genesis-account [address_or_key_name] [coin][,[coin]]",
36+
Short: "Add a genesis account to genesis.json",
37+
Long: `Add a genesis account to genesis.json. The provided account must specify
38+
the account address or key name and a list of initial coins. If a key name is given,
39+
the address will be looked up in the local Keybase. The list of initial tokens must
40+
contain valid denominations. Accounts may optionally be supplied with vesting parameters.
41+
`,
42+
Args: cobra.ExactArgs(2),
43+
RunE: func(cmd *cobra.Command, args []string) error {
44+
clientCtx := client.GetClientContextFromCmd(cmd)
45+
serverCtx := server.GetServerContextFromCmd(cmd)
46+
config := serverCtx.Config
47+
48+
config.SetRoot(clientCtx.HomeDir)
49+
50+
var kr keyring.Keyring
51+
addr, err := addressCodec.StringToBytes(args[0])
52+
if err != nil {
53+
inBuf := bufio.NewReader(cmd.InOrStdin())
54+
keyringBackend, _ := cmd.Flags().GetString(flags.FlagKeyringBackend)
55+
56+
if keyringBackend != "" && clientCtx.Keyring == nil {
57+
var err error
58+
kr, err = keyring.New(sdk.KeyringServiceName(), keyringBackend, clientCtx.HomeDir, inBuf, clientCtx.Codec)
59+
if err != nil {
60+
return err
61+
}
62+
} else {
63+
kr = clientCtx.Keyring
64+
}
65+
66+
k, err := kr.Key(args[0])
67+
if err != nil {
68+
return fmt.Errorf("failed to get address from Keyring: %w", err)
69+
}
70+
71+
addr, err = k.GetAddress()
72+
if err != nil {
73+
return err
74+
}
75+
}
76+
77+
appendflag, _ := cmd.Flags().GetBool(flagAppendMode)
78+
vestingStart, _ := cmd.Flags().GetInt64(flagVestingStart)
79+
vestingCliff, _ := cmd.Flags().GetInt64(flagVestingCliff)
80+
vestingEnd, _ := cmd.Flags().GetInt64(flagVestingEnd)
81+
vestingAmtStr, _ := cmd.Flags().GetString(flagVestingAmt)
82+
moduleNameStr, _ := cmd.Flags().GetString(flagModuleName)
83+
84+
return vestingtypes.AddGenesisAccount(clientCtx.Codec,
85+
addr,
86+
appendflag,
87+
config.GenesisFile(),
88+
args[1],
89+
vestingAmtStr, vestingStart, vestingCliff, vestingEnd,
90+
moduleNameStr)
91+
},
92+
}
93+
94+
cmd.Flags().String(flags.FlagHome, defaultNodeHome, "The application home directory")
95+
cmd.Flags().String(flags.FlagKeyringBackend, flags.DefaultKeyringBackend, "Select keyring's backend (os|file|kwallet|pass|test)")
96+
cmd.Flags().String(flagVestingAmt, "", "amount of coins for vesting accounts")
97+
cmd.Flags().Int64(flagVestingStart, 0, "schedule start time (unix epoch) for vesting accounts")
98+
cmd.Flags().Int64(flagVestingCliff, 0, "schedule cliff time (unix epoch) for vesting accounts")
99+
cmd.Flags().Int64(flagVestingEnd, 0, "schedule end time (unix epoch) for vesting accounts")
100+
cmd.Flags().Bool(flagAppendMode, false, "append the coins to an account already in the genesis.json file")
101+
cmd.Flags().String(flagModuleName, "", "module account name")
102+
flags.AddQueryFlagsToCmd(cmd)
103+
104+
return cmd
105+
}

cmd/axoned/cmd/genaccount_test.go

Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
package cmd_test
2+
3+
import (
4+
"context"
5+
"fmt"
6+
"testing"
7+
8+
"github.com/spf13/viper"
9+
"github.com/stretchr/testify/require"
10+
11+
"cosmossdk.io/log"
12+
13+
"github.com/cosmos/cosmos-sdk/client"
14+
"github.com/cosmos/cosmos-sdk/client/flags"
15+
addresscodec "github.com/cosmos/cosmos-sdk/codec/address"
16+
"github.com/cosmos/cosmos-sdk/crypto/hd"
17+
"github.com/cosmos/cosmos-sdk/crypto/keyring"
18+
"github.com/cosmos/cosmos-sdk/server"
19+
"github.com/cosmos/cosmos-sdk/testutil/testdata"
20+
sdk "github.com/cosmos/cosmos-sdk/types"
21+
"github.com/cosmos/cosmos-sdk/types/module"
22+
moduletestutil "github.com/cosmos/cosmos-sdk/types/module/testutil"
23+
"github.com/cosmos/cosmos-sdk/x/auth"
24+
"github.com/cosmos/cosmos-sdk/x/genutil"
25+
genutilcli "github.com/cosmos/cosmos-sdk/x/genutil/client/cli"
26+
genutiltest "github.com/cosmos/cosmos-sdk/x/genutil/client/testutil"
27+
"github.com/cosmos/cosmos-sdk/x/staking"
28+
)
29+
30+
var testMbm = module.NewBasicManager(
31+
staking.AppModuleBasic{},
32+
genutil.AppModuleBasic{},
33+
)
34+
35+
func TestAddGenesisAccountCmd(t *testing.T) {
36+
_, _, addr1 := testdata.KeyTestPubAddr()
37+
tests := []struct {
38+
name string
39+
addr string
40+
denom string
41+
withKeyring bool
42+
expectErr bool
43+
}{
44+
{
45+
name: "invalid address",
46+
addr: "",
47+
denom: "1000atom",
48+
withKeyring: false,
49+
expectErr: true,
50+
},
51+
{
52+
name: "valid address",
53+
addr: addr1.String(),
54+
denom: "1000atom",
55+
withKeyring: false,
56+
expectErr: false,
57+
},
58+
{
59+
name: "multiple denoms",
60+
addr: addr1.String(),
61+
denom: "1000atom, 2000stake",
62+
withKeyring: false,
63+
expectErr: false,
64+
},
65+
{
66+
name: "with keyring",
67+
addr: "ser",
68+
denom: "1000atom",
69+
withKeyring: true,
70+
expectErr: false,
71+
},
72+
}
73+
74+
for _, tc := range tests {
75+
tc := tc
76+
t.Run(tc.name, func(t *testing.T) {
77+
home := t.TempDir()
78+
logger := log.NewNopLogger()
79+
cfg, err := genutiltest.CreateDefaultCometConfig(home)
80+
require.NoError(t, err)
81+
82+
appCodec := moduletestutil.MakeTestEncodingConfig(auth.AppModuleBasic{}).Codec
83+
err = genutiltest.ExecInitCmd(testMbm, home, appCodec)
84+
require.NoError(t, err)
85+
86+
serverCtx := server.NewContext(viper.New(), cfg, logger)
87+
clientCtx := client.Context{}.WithCodec(appCodec).WithHomeDir(home)
88+
89+
if tc.withKeyring {
90+
path := hd.CreateHDPath(118, 0, 0).String()
91+
kr, err := keyring.New(sdk.KeyringServiceName(), keyring.BackendMemory, home, nil, appCodec)
92+
require.NoError(t, err)
93+
_, _, err = kr.NewMnemonic(tc.addr, keyring.English, path, keyring.DefaultBIP39Passphrase, hd.Secp256k1)
94+
require.NoError(t, err)
95+
clientCtx = clientCtx.WithKeyring(kr)
96+
}
97+
98+
ctx := context.Background()
99+
ctx = context.WithValue(ctx, client.ClientContextKey, &clientCtx)
100+
ctx = context.WithValue(ctx, server.ServerContextKey, serverCtx)
101+
102+
cmd := genutilcli.AddGenesisAccountCmd(home, addresscodec.NewBech32Codec("cosmos"))
103+
cmd.SetArgs([]string{
104+
tc.addr,
105+
tc.denom,
106+
fmt.Sprintf("--%s=home", flags.FlagHome),
107+
})
108+
109+
if tc.expectErr {
110+
require.Error(t, cmd.ExecuteContext(ctx))
111+
} else {
112+
require.NoError(t, cmd.ExecuteContext(ctx))
113+
}
114+
})
115+
}
116+
}

cmd/axoned/cmd/root.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -196,9 +196,18 @@ func initRootCmd(
196196
func genesisCommand(txConfig client.TxConfig, basicManager module.BasicManager, cmds ...*cobra.Command) *cobra.Command {
197197
cmd := genutilcli.Commands(txConfig, basicManager, app.DefaultNodeHome)
198198

199+
// Remove default `add-genesis-account` command and add our custom (integrating the cliff),
200+
for _, command := range cmd.Commands() {
201+
if command.Name() == "add-genesis-account" {
202+
cmd.RemoveCommand(command)
203+
}
204+
}
205+
cmd.AddCommand(AddGenesisAccountCmd(app.DefaultNodeHome, txConfig.SigningContext().AddressCodec()))
206+
199207
for _, subCmd := range cmds {
200208
cmd.AddCommand(subCmd)
201209
}
210+
202211
return cmd
203212
}
204213

docs/command/axoned_genesis_add-genesis-account.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ axoned genesis add-genesis-account [address_or_key_name] [coin][,[coin]] [flags]
2727
--node string <host>:<port> to CometBFT RPC interface for this chain (default "tcp://localhost:26657")
2828
-o, --output string Output format (text|json) (default "text")
2929
--vesting-amount string amount of coins for vesting accounts
30+
--vesting-cliff-time int schedule cliff time (unix epoch) for vesting accounts
3031
--vesting-end-time int schedule end time (unix epoch) for vesting accounts
3132
--vesting-start-time int schedule start time (unix epoch) for vesting accounts
3233
```

docs/command/axoned_tx_vesting_create-cliff-vesting-account.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ Create a new vesting account funded with an allocation of tokens with cliff.
44

55
### Synopsis
66

7-
Create a new vesting account funded with an allocation of tokens. The
7+
Create a new vesting account funded with an allocation of tokens with cliff. The
88
tokens allowed will be start vested but the token will be released only after the cliff time.
99
All vesting accounts created will have their start time
1010
set by the committed block's time. The end_time and cliff_time must be provided as a UNIX epoch

docs/command/axoned_tx_vesting_create-periodic-vesting-account.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ A sequence of coins and period length in seconds. Periods are sequential, in tha
99

1010
An array of coin strings and unix epoch times for coins to vest
1111
\{ "start_time": 1625204910,
12-
"period":[
12+
"periods":[
1313
\{
1414
"coins": "10test",
1515
"length_seconds":2592000 //30 days

docs/proto/vesting.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ continuously vests by unlocking coins after a cliff period linearly with respect
6060
| ----- | ---- | ----- | ----------- |
6161
| `base_vesting_account` | [BaseVestingAccount](#vesting.v1beta1.BaseVestingAccount) | | base_vesting_account implements the VestingAccount interface. It contains all the necessary fields needed for any vesting account implementation |
6262
| `start_time` | [int64](#int64) | | start_time defines the time at which the vesting period begins |
63-
| `cliff_time` | [int64](#int64) | | |
63+
| `cliff_time` | [int64](#int64) | | cliff_time defines the time at which the first portion of the vesting is unlocked |
6464

6565
<a name="vesting.v1beta1.ContinuousVestingAccount"></a>
6666

@@ -94,7 +94,7 @@ Period defines a length of time and amount of coins that will vest.
9494

9595
| Field | Type | Label | Description |
9696
| ----- | ---- | ----- | ----------- |
97-
| `length` | [int64](#int64) | | |
97+
| `length` | [int64](#int64) | | Period duration in seconds. |
9898
| `amount` | [cosmos.base.v1beta1.Coin](#cosmos.base.v1beta1.Coin) | repeated | |
9999

100100
<a name="vesting.v1beta1.PeriodicVestingAccount"></a>
@@ -150,7 +150,7 @@ account.
150150
| `to_address` | [string](#string) | | |
151151
| `amount` | [cosmos.base.v1beta1.Coin](#cosmos.base.v1beta1.Coin) | repeated | |
152152
| `end_time` | [int64](#int64) | | |
153-
| `cliff_time` | [int64](#int64) | | |
153+
| `cliff_time` | [int64](#int64) | | cliff time as unix time (in seconds) is the time at which the first portion of the vesting is unlocked. |
154154

155155
<a name="vesting.v1beta1.MsgCreateCliffVestingAccountResponse"></a>
156156

@@ -218,7 +218,7 @@ account.
218218
| `from_address` | [string](#string) | | |
219219
| `to_address` | [string](#string) | | |
220220
| `amount` | [cosmos.base.v1beta1.Coin](#cosmos.base.v1beta1.Coin) | repeated | |
221-
| `end_time` | [int64](#int64) | | |
221+
| `end_time` | [int64](#int64) | | end of vesting as unix time (in seconds). |
222222
| `delayed` | [bool](#bool) | | |
223223

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

proto/buf.gen.doc.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,4 @@ plugins:
44
- name: doc
55
out: ../docs/proto
66
opt:
7-
- ../docs/proto/templates/protodoc-markdown.tmpl,docs.md
7+
- ../docs/proto/templates/protodoc-markdown.tmpl,docs.md:module/*

proto/buf.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
version: v1
22
name: buf.build/axone-protocol/axoned
33
deps:
4-
- buf.build/cosmos/cosmos-sdk:v0.50.1
4+
- buf.build/cosmos/cosmos-sdk:v0.50.0
55
- buf.build/cosmos/cosmos-proto
66
- buf.build/cosmos/gogo-proto
77
- buf.build/googleapis/googleapis

proto/vesting/module/v1/module.proto

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
syntax = "proto3";
2+
3+
package vesting.module.v1;
4+
5+
import "cosmos/app/v1alpha1/module.proto";
6+
7+
// Module is the config object of the vesting module.
8+
message Module {
9+
option (cosmos.app.v1alpha1.module) = {
10+
go_import: "github.com/axone-protocol/axoned/x/vesting"
11+
};
12+
}

proto/vesting/v1beta1/tx.proto

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,11 +46,13 @@ message MsgCreateVestingAccount {
4646
repeated cosmos.base.v1beta1.Coin amount = 3 [
4747
(gogoproto.nullable) = false,
4848
(amino.dont_omitempty) = true,
49+
(amino.encoding) = "legacy_coins",
4950
(gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins"
5051
];
5152

53+
// end of vesting as unix time (in seconds).
5254
int64 end_time = 4;
53-
bool delayed = 6;
55+
bool delayed = 5;
5456
}
5557

5658
// MsgCreateVestingAccountResponse defines the Msg/CreateVestingAccount response type.
@@ -70,6 +72,7 @@ message MsgCreatePermanentLockedAccount {
7072
repeated cosmos.base.v1beta1.Coin amount = 3 [
7173
(gogoproto.nullable) = false,
7274
(amino.dont_omitempty) = true,
75+
(amino.encoding) = "legacy_coins",
7376
(gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins"
7477
];
7578
}
@@ -85,7 +88,7 @@ message MsgCreatePermanentLockedAccountResponse {}
8588
// Since: cosmos-sdk 0.46
8689
message MsgCreatePeriodicVestingAccount {
8790
option (cosmos.msg.v1.signer) = "from_address";
88-
option (amino.name) = "cosmos-sdk/MsgCreatePeriodicVestingAccount";
91+
option (amino.name) = "cosmos-sdk/MsgCreatePeriodVestAccount";
8992

9093
option (gogoproto.equal) = false;
9194

@@ -122,6 +125,7 @@ message MsgCreateCliffVestingAccount {
122125
];
123126

124127
int64 end_time = 4;
128+
// cliff time as unix time (in seconds) is the time at which the first portion of the vesting is unlocked.
125129
int64 cliff_time = 5;
126130
}
127131

0 commit comments

Comments
 (0)