Skip to content

Commit

Permalink
feat: Add metadata field to proposal
Browse files Browse the repository at this point in the history
  • Loading branch information
amaury1093 committed Jan 21, 2022
1 parent eb01537 commit 0455996
Show file tree
Hide file tree
Showing 21 changed files with 354 additions and 183 deletions.
3 changes: 3 additions & 0 deletions proto/cosmos/gov/v1beta2/gov.proto
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,9 @@ message Proposal {
repeated cosmos.base.v1beta1.Coin total_deposit = 7 [(gogoproto.nullable) = false];
google.protobuf.Timestamp voting_start_time = 8 [(gogoproto.stdtime) = true];
google.protobuf.Timestamp voting_end_time = 9 [(gogoproto.stdtime) = true];

// metadata is any arbitrary metadata to attached to the proposal.
bytes metadata = 10;
}

// ProposalStatus enumerates the valid statuses of a proposal.
Expand Down
2 changes: 2 additions & 0 deletions proto/cosmos/gov/v1beta2/tx.proto
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ message MsgSubmitProposal {
repeated google.protobuf.Any messages = 1;
repeated cosmos.base.v1beta1.Coin initial_deposit = 2 [(gogoproto.nullable) = false];
string proposer = 3 [(cosmos_proto.scalar) = "cosmos.AddressString"];
// metadata is any arbitrary metadata to attached to the proposal.
bytes metadata = 4;
}

// MsgSubmitProposalResponse defines the Msg/SubmitProposal response type.
Expand Down
3 changes: 2 additions & 1 deletion simapp/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -302,9 +302,10 @@ func NewSimApp(
AddRoute(paramproposal.RouterKey, params.NewParamChangeProposalHandler(app.ParamsKeeper)).
AddRoute(distrtypes.RouterKey, distr.NewCommunityPoolSpendProposalHandler(app.DistrKeeper)).
AddRoute(upgradetypes.RouterKey, upgrade.NewSoftwareUpgradeProposalHandler(app.UpgradeKeeper))
govMaxMetadataLen := uint64(10000)
govKeeper := govkeeper.NewKeeper(
appCodec, keys[govtypes.StoreKey], app.GetSubspace(govtypes.ModuleName), app.AccountKeeper, app.BankKeeper,
&stakingKeeper, govRouter, app.msgSvcRouter,
&stakingKeeper, govRouter, app.msgSvcRouter, govMaxMetadataLen,
)

app.GovKeeper = *govKeeper.SetHooks(
Expand Down
10 changes: 7 additions & 3 deletions x/gov/abci_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ func TestTickExpiredDepositPeriod(t *testing.T) {
[]sdk.Msg{mkTestLegacyContent(t)},
sdk.Coins{sdk.NewInt64Coin(sdk.DefaultBondDenom, 5)},
addrs[0].String(),
nil,
)
require.NoError(t, err)

Expand Down Expand Up @@ -89,6 +90,7 @@ func TestTickMultipleExpiredDepositPeriod(t *testing.T) {
[]sdk.Msg{mkTestLegacyContent(t)},
sdk.Coins{sdk.NewInt64Coin(sdk.DefaultBondDenom, 5)},
addrs[0].String(),
nil,
)
require.NoError(t, err)

Expand All @@ -112,6 +114,7 @@ func TestTickMultipleExpiredDepositPeriod(t *testing.T) {
[]sdk.Msg{mkTestLegacyContent(t)},
sdk.Coins{sdk.NewInt64Coin(sdk.DefaultBondDenom, 5)},
addrs[0].String(),
nil,
)
require.NoError(t, err)

Expand Down Expand Up @@ -169,6 +172,7 @@ func TestTickPassedDepositPeriod(t *testing.T) {
[]sdk.Msg{mkTestLegacyContent(t)},
sdk.Coins{sdk.NewInt64Coin(sdk.DefaultBondDenom, 5)},
addrs[0].String(),
nil,
)
require.NoError(t, err)

Expand Down Expand Up @@ -221,7 +225,7 @@ func TestTickPassedVotingPeriod(t *testing.T) {
activeQueue.Close()

proposalCoins := sdk.Coins{sdk.NewCoin(sdk.DefaultBondDenom, app.StakingKeeper.TokensFromConsensusPower(ctx, 5))}
newProposalMsg, err := v1beta2.NewMsgSubmitProposal([]sdk.Msg{mkTestLegacyContent(t)}, proposalCoins, addrs[0].String())
newProposalMsg, err := v1beta2.NewMsgSubmitProposal([]sdk.Msg{mkTestLegacyContent(t)}, proposalCoins, addrs[0].String(), nil)
require.NoError(t, err)

wrapCtx := sdk.WrapSDKContext(ctx)
Expand Down Expand Up @@ -289,7 +293,7 @@ func TestProposalPassedEndblocker(t *testing.T) {
require.NotNil(t, macc)
initialModuleAccCoins := app.BankKeeper.GetAllBalances(ctx, macc.GetAddress())

proposal, err := app.GovKeeper.SubmitProposal(ctx, []sdk.Msg{mkTestLegacyContent(t)})
proposal, err := app.GovKeeper.SubmitProposal(ctx, []sdk.Msg{mkTestLegacyContent(t)}, nil)
require.NoError(t, err)

proposalCoins := sdk.Coins{sdk.NewCoin(sdk.DefaultBondDenom, app.StakingKeeper.TokensFromConsensusPower(ctx, 10))}
Expand Down Expand Up @@ -339,7 +343,7 @@ func TestEndBlockerProposalHandlerFailed(t *testing.T) {
// Create a proposal where the handler will pass for the test proposal
// because the value of contextKeyBadProposal is true.
ctx = ctx.WithValue(contextKeyBadProposal, true)
proposal, err := app.GovKeeper.SubmitProposal(ctx, []sdk.Msg{mkTestLegacyContent(t)})
proposal, err := app.GovKeeper.SubmitProposal(ctx, []sdk.Msg{mkTestLegacyContent(t)}, nil)
require.NoError(t, err)

proposalCoins := sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, app.StakingKeeper.TokensFromConsensusPower(ctx, 10)))
Expand Down
4 changes: 2 additions & 2 deletions x/gov/genesis_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,11 @@ func TestImportExportQueues(t *testing.T) {

ctx = app.BaseApp.NewContext(false, tmproto.Header{})
// Create two proposals, put the second into the voting period
proposal1, err := app.GovKeeper.SubmitProposal(ctx, []sdk.Msg{mkTestLegacyContent(t)})
proposal1, err := app.GovKeeper.SubmitProposal(ctx, []sdk.Msg{mkTestLegacyContent(t)}, nil)
require.NoError(t, err)
proposalID1 := proposal1.ProposalId

proposal2, err := app.GovKeeper.SubmitProposal(ctx, []sdk.Msg{mkTestLegacyContent(t)})
proposal2, err := app.GovKeeper.SubmitProposal(ctx, []sdk.Msg{mkTestLegacyContent(t)}, nil)
require.NoError(t, err)
proposalID2 := proposal2.ProposalId

Expand Down
4 changes: 2 additions & 2 deletions x/gov/keeper/deposit_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ func TestDeposits(t *testing.T) {
TestAddrs := simapp.AddTestAddrsIncremental(app, ctx, 2, sdk.NewInt(10000000))

tp := TestProposal
proposal, err := app.GovKeeper.SubmitProposal(ctx, tp)
proposal, err := app.GovKeeper.SubmitProposal(ctx, tp, nil)
require.NoError(t, err)
proposalID := proposal.ProposalId

Expand Down Expand Up @@ -101,7 +101,7 @@ func TestDeposits(t *testing.T) {
require.Equal(t, addr1Initial, app.BankKeeper.GetAllBalances(ctx, TestAddrs[1]))

// Test delete and burn deposits
proposal, err = app.GovKeeper.SubmitProposal(ctx, tp)
proposal, err = app.GovKeeper.SubmitProposal(ctx, tp, nil)
require.NoError(t, err)
proposalID = proposal.ProposalId
_, err = app.GovKeeper.AddDeposit(ctx, proposalID, TestAddrs[0], fourStake)
Expand Down
14 changes: 7 additions & 7 deletions x/gov/keeper/grpc_query_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ func (suite *KeeperTestSuite) TestGRPCQueryProposal() {
testProposal := v1beta1.NewTextProposal("Proposal", "testing proposal")
msgContent, err := v1beta2.NewLegacyContent(testProposal, govAcct.String())
suite.Require().NoError(err)
submittedProposal, err := app.GovKeeper.SubmitProposal(ctx, []sdk.Msg{msgContent})
submittedProposal, err := app.GovKeeper.SubmitProposal(ctx, []sdk.Msg{msgContent}, nil)
suite.Require().NoError(err)
suite.Require().NotEmpty(submittedProposal)

Expand Down Expand Up @@ -116,7 +116,7 @@ func (suite *KeeperTestSuite) TestGRPCQueryProposals() {
testProposal := []sdk.Msg{
v1beta2.NewMsgVote(govAddress, uint64(i), v1beta2.OptionYes),
}
proposal, err := app.GovKeeper.SubmitProposal(ctx, testProposal)
proposal, err := app.GovKeeper.SubmitProposal(ctx, testProposal, nil)
suite.Require().NotEmpty(proposal)
suite.Require().NoError(err)
testProposals = append(testProposals, &proposal)
Expand Down Expand Up @@ -291,7 +291,7 @@ func (suite *KeeperTestSuite) TestGRPCQueryVote() {
"no votes present",
func() {
var err error
proposal, err = app.GovKeeper.SubmitProposal(ctx, TestProposal)
proposal, err = app.GovKeeper.SubmitProposal(ctx, TestProposal, nil)
suite.Require().NoError(err)

req = &v1beta2.QueryVoteRequest{
Expand Down Expand Up @@ -396,7 +396,7 @@ func (suite *KeeperTestSuite) TestGRPCQueryVotes() {
"create a proposal and get votes",
func() {
var err error
proposal, err = app.GovKeeper.SubmitProposal(ctx, TestProposal)
proposal, err = app.GovKeeper.SubmitProposal(ctx, TestProposal, nil)
suite.Require().NoError(err)

req = &v1beta2.QueryVotesRequest{
Expand Down Expand Up @@ -588,7 +588,7 @@ func (suite *KeeperTestSuite) TestGRPCQueryDeposit() {
"no deposits proposal",
func() {
var err error
proposal, err = app.GovKeeper.SubmitProposal(ctx, TestProposal)
proposal, err = app.GovKeeper.SubmitProposal(ctx, TestProposal, nil)
suite.Require().NoError(err)
suite.Require().NotNil(proposal)

Expand Down Expand Up @@ -677,7 +677,7 @@ func (suite *KeeperTestSuite) TestGRPCQueryDeposits() {
"create a proposal and get deposits",
func() {
var err error
proposal, err = app.GovKeeper.SubmitProposal(ctx, TestProposal)
proposal, err = app.GovKeeper.SubmitProposal(ctx, TestProposal, nil)
suite.Require().NoError(err)

req = &v1beta2.QueryDepositsRequest{
Expand Down Expand Up @@ -769,7 +769,7 @@ func (suite *KeeperTestSuite) TestGRPCQueryTally() {
"create a proposal and get tally",
func() {
var err error
proposal, err = app.GovKeeper.SubmitProposal(ctx, TestProposal)
proposal, err = app.GovKeeper.SubmitProposal(ctx, TestProposal, nil)
suite.Require().NoError(err)
suite.Require().NotNil(proposal)

Expand Down
4 changes: 2 additions & 2 deletions x/gov/keeper/hooks_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ func TestHooks(t *testing.T) {
require.False(t, govHooksReceiver.AfterProposalVotingPeriodEndedValid)

tp := TestProposal
_, err := app.GovKeeper.SubmitProposal(ctx, tp)
_, err := app.GovKeeper.SubmitProposal(ctx, tp, nil)
require.NoError(t, err)
require.True(t, govHooksReceiver.AfterProposalSubmissionValid)

Expand All @@ -75,7 +75,7 @@ func TestHooks(t *testing.T) {

require.True(t, govHooksReceiver.AfterProposalFailedMinDepositValid)

p2, err := app.GovKeeper.SubmitProposal(ctx, tp)
p2, err := app.GovKeeper.SubmitProposal(ctx, tp, nil)
require.NoError(t, err)

activated, err := app.GovKeeper.AddDeposit(ctx, p2.ProposalId, addrs[0], minDeposit)
Expand Down
21 changes: 13 additions & 8 deletions x/gov/keeper/keeper.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,9 @@ type Keeper struct {

// Msg server router
router *middleware.MsgServiceRouter

// maxMetadataLen defines the maximum proposal metadata length.
maxMetadataLen uint64
}

// NewKeeper returns a governance keeper. It handles:
Expand All @@ -54,6 +57,7 @@ func NewKeeper(
cdc codec.BinaryCodec, key storetypes.StoreKey, paramSpace types.ParamSubspace,
authKeeper types.AccountKeeper, bankKeeper types.BankKeeper, sk types.StakingKeeper,
legacyRouter v1beta1.Router, router *middleware.MsgServiceRouter,
maxMetadataLen uint64,
) Keeper {

// ensure governance module account is set
Expand All @@ -67,14 +71,15 @@ func NewKeeper(
legacyRouter.Seal()

return Keeper{
storeKey: key,
paramSpace: paramSpace,
authKeeper: authKeeper,
bankKeeper: bankKeeper,
sk: sk,
cdc: cdc,
legacyRouter: legacyRouter,
router: router,
storeKey: key,
paramSpace: paramSpace,
authKeeper: authKeeper,
bankKeeper: bankKeeper,
sk: sk,
cdc: cdc,
legacyRouter: legacyRouter,
router: router,
maxMetadataLen: maxMetadataLen,
}
}

Expand Down
14 changes: 7 additions & 7 deletions x/gov/keeper/keeper_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,17 +51,17 @@ func TestIncrementProposalNumber(t *testing.T) {
ctx := app.BaseApp.NewContext(false, tmproto.Header{})

tp := TestProposal
_, err := app.GovKeeper.SubmitProposal(ctx, tp)
_, err := app.GovKeeper.SubmitProposal(ctx, tp, nil)
require.NoError(t, err)
_, err = app.GovKeeper.SubmitProposal(ctx, tp)
_, err = app.GovKeeper.SubmitProposal(ctx, tp, nil)
require.NoError(t, err)
_, err = app.GovKeeper.SubmitProposal(ctx, tp)
_, err = app.GovKeeper.SubmitProposal(ctx, tp, nil)
require.NoError(t, err)
_, err = app.GovKeeper.SubmitProposal(ctx, tp)
_, err = app.GovKeeper.SubmitProposal(ctx, tp, nil)
require.NoError(t, err)
_, err = app.GovKeeper.SubmitProposal(ctx, tp)
_, err = app.GovKeeper.SubmitProposal(ctx, tp, nil)
require.NoError(t, err)
proposal6, err := app.GovKeeper.SubmitProposal(ctx, tp)
proposal6, err := app.GovKeeper.SubmitProposal(ctx, tp, nil)
require.NoError(t, err)

require.Equal(t, uint64(6), proposal6.ProposalId)
Expand All @@ -73,7 +73,7 @@ func TestProposalQueues(t *testing.T) {

// create test proposals
tp := TestProposal
proposal, err := app.GovKeeper.SubmitProposal(ctx, tp)
proposal, err := app.GovKeeper.SubmitProposal(ctx, tp, nil)
require.NoError(t, err)

inactiveIterator := app.GovKeeper.InactiveProposalQueueIterator(ctx, *proposal.DepositEndTime)
Expand Down
3 changes: 2 additions & 1 deletion x/gov/keeper/msg_server.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ func (k msgServer) SubmitProposal(goCtx context.Context, msg *v1beta2.MsgSubmitP
return nil, err
}

proposal, err := k.Keeper.SubmitProposal(ctx, proposalMsgs)
proposal, err := k.Keeper.SubmitProposal(ctx, proposalMsgs, msg.Metadata)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -230,6 +230,7 @@ func (k legacyMsgServer) SubmitProposal(goCtx context.Context, msg *v1beta1.MsgS
[]sdk.Msg{contentMsg},
msg.InitialDeposit,
msg.Proposer,
nil,
)
if err != nil {
return nil, err
Expand Down
6 changes: 5 additions & 1 deletion x/gov/keeper/proposal.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,11 @@ import (
)

// SubmitProposal create new proposal given an array of messages
func (keeper Keeper) SubmitProposal(ctx sdk.Context, messages []sdk.Msg) (v1beta2.Proposal, error) {
func (keeper Keeper) SubmitProposal(ctx sdk.Context, messages []sdk.Msg, metadata []byte) (v1beta2.Proposal, error) {
if metadata != nil && len(metadata) > int(keeper.maxMetadataLen) {
return v1beta2.Proposal{}, types.ErrMetadataTooLong.Wrapf("got metadata with length %d", len(metadata))
}

// Will hold a comma-separated string of all Msg type URLs.
msgsStr := ""

Expand Down
25 changes: 15 additions & 10 deletions x/gov/keeper/proposal_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package keeper_test

import (
"bytes"
"errors"
"fmt"
"strings"
Expand All @@ -18,7 +19,7 @@ import (

func (suite *KeeperTestSuite) TestGetSetProposal() {
tp := TestProposal
proposal, err := suite.app.GovKeeper.SubmitProposal(suite.ctx, tp)
proposal, err := suite.app.GovKeeper.SubmitProposal(suite.ctx, tp, nil)
suite.Require().NoError(err)
proposalID := proposal.ProposalId
suite.app.GovKeeper.SetProposal(suite.ctx, proposal)
Expand All @@ -30,7 +31,7 @@ func (suite *KeeperTestSuite) TestGetSetProposal() {

func (suite *KeeperTestSuite) TestActivateVotingPeriod() {
tp := TestProposal
proposal, err := suite.app.GovKeeper.SubmitProposal(suite.ctx, tp)
proposal, err := suite.app.GovKeeper.SubmitProposal(suite.ctx, tp, nil)
suite.Require().NoError(err)

suite.Require().Nil(proposal.VotingStartTime)
Expand All @@ -56,28 +57,32 @@ func (invalidProposalRoute) ProposalRoute() string { return "nonexistingroute" }
func (suite *KeeperTestSuite) TestSubmitProposal() {
govAcct := suite.app.GovKeeper.GetGovernanceAccount(suite.ctx).GetAddress().String()
_, _, randomAddr := testdata.KeyTestPubAddr()
tp := v1beta1.TextProposal{Title: "title", Description: "description"}

testCases := []struct {
content v1beta1.Content
authority string
metadata []byte
expectedErr error
}{
{&v1beta1.TextProposal{Title: "title", Description: "description"}, govAcct, nil},
{&tp, govAcct, nil, nil},
// Keeper does not check the validity of title and description, no error
{&v1beta1.TextProposal{Title: "", Description: "description"}, govAcct, nil},
{&v1beta1.TextProposal{Title: strings.Repeat("1234567890", 100), Description: "description"}, govAcct, nil},
{&v1beta1.TextProposal{Title: "title", Description: ""}, govAcct, nil},
{&v1beta1.TextProposal{Title: "title", Description: strings.Repeat("1234567890", 1000)}, govAcct, nil},
{&v1beta1.TextProposal{Title: "", Description: "description"}, govAcct, nil, nil},
{&v1beta1.TextProposal{Title: strings.Repeat("1234567890", 100), Description: "description"}, govAcct, nil, nil},
{&v1beta1.TextProposal{Title: "title", Description: ""}, govAcct, nil, nil},
{&v1beta1.TextProposal{Title: "title", Description: strings.Repeat("1234567890", 1000)}, govAcct, nil, nil},
// error when metadata is too long (>10000)
{&tp, govAcct, bytes.Repeat([]byte{42}, 10001), types.ErrMetadataTooLong},
// error when signer is not gov acct
{&v1beta1.TextProposal{Title: "title", Description: "description"}, randomAddr.String(), types.ErrInvalidSigner},
{&tp, randomAddr.String(), nil, types.ErrInvalidSigner},
// error only when invalid route
{&invalidProposalRoute{}, govAcct, types.ErrNoProposalHandlerExists},
{&invalidProposalRoute{}, govAcct, nil, types.ErrNoProposalHandlerExists},
}

for i, tc := range testCases {
prop, err := v1beta2.NewLegacyContent(tc.content, tc.authority)
suite.Require().NoError(err)
_, err = suite.app.GovKeeper.SubmitProposal(suite.ctx, []sdk.Msg{prop})
_, err = suite.app.GovKeeper.SubmitProposal(suite.ctx, []sdk.Msg{prop}, tc.metadata)
suite.Require().True(errors.Is(tc.expectedErr, err), "tc #%d; got: %v, expected: %v", i, err, tc.expectedErr)
}
}
Expand Down
Loading

0 comments on commit 0455996

Please sign in to comment.