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: use proposal for cross chain parameter governance #110

Merged
merged 12 commits into from
Feb 24, 2023
2 changes: 2 additions & 0 deletions proto/cosmos/params/v1beta1/params.proto
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ message ParameterChangeProposal {
string title = 1;
string description = 2;
repeated ParamChange changes = 3 [(gogoproto.nullable) = false];
bool cross_chain = 4; // flag for cross chain proposal
repeated string addresses = 5; // used with cross_chain field to specify destination smart contract address(es)
unclezoro marked this conversation as resolved.
Show resolved Hide resolved
}

// ParamChange defines an individual parameter change, for use in
Expand Down
2 changes: 0 additions & 2 deletions types/context.go
Original file line number Diff line number Diff line change
Expand Up @@ -290,12 +290,10 @@ func (c Context) TransientStore(key storetypes.StoreKey) KVStore {
func (c Context) CacheContext() (cc Context, writeCache func()) {
cms := c.MultiStore().CacheMultiStore()
cc = c.WithMultiStore(cms).WithEventManager(NewEventManager())

writeCache = func() {
c.EventManager().EmitEvents(cc.EventManager().Events())
cms.Write()
}

return cc, writeCache
}

Expand Down
14 changes: 10 additions & 4 deletions x/distribution/client/cli/tx.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@ import (
"fmt"
"strings"

authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
govtypes "github.com/cosmos/cosmos-sdk/x/gov/types"
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

pls fix the imports order

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

make lint-fix does not find, what should fix?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you can refer to the format.sh in greenfield repo


"github.com/spf13/cobra"
"github.com/spf13/pflag"

Expand All @@ -13,7 +16,7 @@ import (
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/version"
"github.com/cosmos/cosmos-sdk/x/distribution/types"
govtypes "github.com/cosmos/cosmos-sdk/x/gov/types/v1beta1"
govv1 "github.com/cosmos/cosmos-sdk/x/gov/types/v1"
)

// Transaction flags for the x/distribution module
Expand Down Expand Up @@ -341,12 +344,15 @@ Where proposal.json contains:
return err
}
content := types.NewCommunityPoolSpendProposal(proposal.Title, proposal.Description, recpAddr, amount)

msg, err := govtypes.NewMsgSubmitProposal(content, deposit, from)
govAcctAddress := authtypes.NewModuleAddress(govtypes.ModuleName).String()
contentMsg, err := govv1.NewLegacyContent(content, govAcctAddress)
if err != nil {
return err
}
msg, err := govv1.NewMsgSubmitProposal([]sdk.Msg{contentMsg}, deposit, from.String(), "")
if err != nil {
return err
}

return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msg)
},
}
Expand Down
2 changes: 1 addition & 1 deletion x/feegrant/client/testutil/suite.go
Original file line number Diff line number Diff line change
Expand Up @@ -820,7 +820,7 @@ func (s *IntegrationTestSuite) TestFilteredFeeAllowance() {
}
spendLimit := sdk.NewCoin("stake", sdk.NewInt(1000))

allowMsgs := strings.Join([]string{sdk.MsgTypeURL(&govv1beta1.MsgSubmitProposal{}), sdk.MsgTypeURL(&govv1.MsgVoteWeighted{})}, ",")
allowMsgs := strings.Join([]string{sdk.MsgTypeURL(&govv1.MsgSubmitProposal{}), sdk.MsgTypeURL(&govv1.MsgVoteWeighted{})}, ",")

testCases := []struct {
name string
Expand Down
15 changes: 10 additions & 5 deletions x/gov/abci.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,8 +57,9 @@ func EndBlocker(ctx sdk.Context, keeper keeper.Keeper) {

if passes {
var (
idx int
msg sdk.Msg
idx int
events sdk.Events
msg sdk.Msg
)

// attempt to execute all messages within the passed proposal
Expand All @@ -70,10 +71,13 @@ func EndBlocker(ctx sdk.Context, keeper keeper.Keeper) {
if err == nil {
for idx, msg = range messages {
handler := keeper.Router().Handler(msg)
_, err = handler(cacheCtx, msg)
var res *sdk.Result
res, err = handler(cacheCtx, msg)
if err != nil {
break
}

events = append(events, res.GetEvents()...)
}
}

Expand All @@ -83,9 +87,10 @@ func EndBlocker(ctx sdk.Context, keeper keeper.Keeper) {
proposal.Status = v1.StatusPassed
tagValue = types.AttributeValueProposalPassed
logMsg = "passed"

// write state to the underlying multi-store
writeCache()

// propagate the msg events to the current context
ctx.EventManager().EmitEvents(events)
} else {
proposal.Status = v1.StatusFailed
tagValue = types.AttributeValueProposalFailed
Expand Down
10 changes: 8 additions & 2 deletions x/gov/client/cli/tx.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import (
"strconv"
"strings"

authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

pls fix the imports order

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed

"github.com/spf13/cobra"

"github.com/cosmos/cosmos-sdk/client"
Expand Down Expand Up @@ -186,11 +188,15 @@ $ %s tx gov submit-legacy-proposal --title="Test Proposal" --description="My awe
return fmt.Errorf("failed to create proposal content: unknown proposal type %s", proposal.Type)
}

msg, err := v1beta1.NewMsgSubmitProposal(content, amount, clientCtx.GetFromAddress())
govAcctAddress := authtypes.NewModuleAddress(types.ModuleName).String()
contentMsg, err := v1.NewLegacyContent(content, govAcctAddress)
if err != nil {
return err
}
msg, err := v1.NewMsgSubmitProposal([]sdk.Msg{contentMsg}, amount, clientCtx.GetFromAddress().String(), "")
if err != nil {
return fmt.Errorf("invalid message: %w", err)
}

return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msg)
},
}
Expand Down
1 change: 0 additions & 1 deletion x/gov/keeper/proposal.go
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,6 @@ func (keeper Keeper) SubmitProposal(ctx sdk.Context, messages []sdk.Msg, metadat
sdk.NewAttribute(types.AttributeKeyProposalMessages, msgsStr),
),
)

return proposal, nil
}

Expand Down
6 changes: 1 addition & 5 deletions x/gov/module.go
Original file line number Diff line number Diff line change
Expand Up @@ -156,13 +156,9 @@ func (am AppModule) LegacyQuerierHandler(legacyQuerierCdc *codec.LegacyAmino) sd
// RegisterServices registers module services.
func (am AppModule) RegisterServices(cfg module.Configurator) {
msgServer := keeper.NewMsgServerImpl(am.keeper)
v1beta1.RegisterMsgServer(cfg.MsgServer(), keeper.NewLegacyMsgServerImpl(am.accountKeeper.GetModuleAddress(types.ModuleName).String(), msgServer))
v1.RegisterMsgServer(cfg.MsgServer(), msgServer)

legacyQueryServer := keeper.NewLegacyQueryServer(am.keeper)
v1beta1.RegisterQueryServer(cfg.QueryServer(), legacyQueryServer)
v1.RegisterMsgServer(cfg.MsgServer(), msgServer)
v1.RegisterQueryServer(cfg.QueryServer(), am.keeper)

m := keeper.NewMigrator(am.keeper)
err := cfg.RegisterMigration(types.ModuleName, 1, m.Migrate1to2)
if err != nil {
Expand Down
1 change: 0 additions & 1 deletion x/gov/types/v1/content.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ func NewLegacyContent(content v1beta1.Content, authority string) (*MsgExecLegacy
if !ok {
return nil, fmt.Errorf("%T does not implement proto.Message", content)
}

any, err := codectypes.NewAnyWithValue(msg)
if err != nil {
return nil, err
Expand Down
14 changes: 10 additions & 4 deletions x/params/client/cli/tx.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,16 @@ import (
"fmt"
"strings"

authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
govtypes "github.com/cosmos/cosmos-sdk/x/gov/types"
govv1 "github.com/cosmos/cosmos-sdk/x/gov/types/v1"

"github.com/spf13/cobra"

"github.com/cosmos/cosmos-sdk/client"
"github.com/cosmos/cosmos-sdk/client/tx"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/version"
govv1beta1 "github.com/cosmos/cosmos-sdk/x/gov/types/v1beta1"
paramscutils "github.com/cosmos/cosmos-sdk/x/params/client/utils"
paramproposal "github.com/cosmos/cosmos-sdk/x/params/types/proposal"
)
Expand Down Expand Up @@ -75,12 +78,15 @@ Where proposal.json contains:
if err != nil {
return err
}

msg, err := govv1beta1.NewMsgSubmitProposal(content, deposit, from)
govAcctAddress := authtypes.NewModuleAddress(govtypes.ModuleName).String()
contentMsg, err := govv1.NewLegacyContent(content, govAcctAddress)
if err != nil {
return err
}
msg, err := govv1.NewMsgSubmitProposal([]sdk.Msg{contentMsg}, deposit, from.String(), "")
if err != nil {
return err
}

return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msg)
},
}
Expand Down
36 changes: 36 additions & 0 deletions x/params/client/cli/tx_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,3 +40,39 @@ func TestParseProposal(t *testing.T) {
},
}, proposal.Changes)
}

func TestParseCrossChainProposal(t *testing.T) {
cdc := codec.NewLegacyAmino()
okJSON := testutil.WriteToNewTempFile(t, `
{
"title": "BSC smart contract upgrade",
"description": "BSC smart contract upgrade",
"changes": [
{
"subspace": "BSC",
"key": "upgrade",
"value": "0x8f86403A4DE0BB5791fa46B8e795C547942fE4Cf"
}
],
"deposit": "1000000000000BNB",
"cross_chain": true,
"addresses": ["0x6c615C766EE6b7e69275b0D070eF50acc93ab880"]
}
`)
proposal, err := utils.ParseParamChangeProposalJSON(cdc, okJSON.Name())
require.NoError(t, err)

require.Equal(t, "BSC smart contract upgrade", proposal.Title)
require.Equal(t, "BSC smart contract upgrade", proposal.Description)
require.Equal(t, "1000000000000BNB", proposal.Deposit)

require.Equal(t, true, proposal.CrossChain)
require.Equal(t, "0x6c615C766EE6b7e69275b0D070eF50acc93ab880", proposal.Addresses[0])
require.Equal(t, utils.ParamChangesJSON{
{
Subspace: "BSC",
Key: "upgrade",
Value: []byte{0x22, 0x30, 0x78, 0x38, 0x66, 0x38, 0x36, 0x34, 0x30, 0x33, 0x41, 0x34, 0x44, 0x45, 0x30, 0x42, 0x42, 0x35, 0x37, 0x39, 0x31, 0x66, 0x61, 0x34, 0x36, 0x42, 0x38, 0x65, 0x37, 0x39, 0x35, 0x43, 0x35, 0x34, 0x37, 0x39, 0x34, 0x32, 0x66, 0x45, 0x34, 0x43, 0x66, 0x22},
},
}, proposal.Changes)
}
3 changes: 3 additions & 0 deletions x/params/client/utils/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ type (
// ParamChangesJSON defines a slice of ParamChangeJSON objects which can be
// converted to a slice of ParamChange objects.
ParamChangesJSON []ParamChangeJSON
Addresses []string

// ParamChangeJSON defines a parameter change used in JSON input. This
// allows values to be specified in raw JSON instead of being string encoded.
Expand All @@ -28,6 +29,8 @@ type (
Description string `json:"description" yaml:"description"`
Changes ParamChangesJSON `json:"changes" yaml:"changes"`
Deposit string `json:"deposit" yaml:"deposit"`
CrossChain bool `json:"cross_chain" yaml:"cross_chain"`
Addresses Addresses `json:"addresses" yaml:"addresses"`
}
)

Expand Down
16 changes: 11 additions & 5 deletions x/params/keeper/keeper.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,12 @@ import (

// Keeper of the global paramstore
type Keeper struct {
cdc codec.BinaryCodec
legacyAmino *codec.LegacyAmino
key storetypes.StoreKey
tkey storetypes.StoreKey
spaces map[string]*types.Subspace
cdc codec.BinaryCodec
legacyAmino *codec.LegacyAmino
key storetypes.StoreKey
tkey storetypes.StoreKey
spaces map[string]*types.Subspace
crossChainKeeper *types.CrossChainKeeper
}

// NewKeeper constructs a params keeper
Expand All @@ -29,6 +30,11 @@ func NewKeeper(cdc codec.BinaryCodec, legacyAmino *codec.LegacyAmino, key, tkey
}
}

// SetCrossChainKeeper sets the crosschainkeeper after its initialization
func (k *Keeper) SetCrossChainKeeper(crossChainKeeper types.CrossChainKeeper) {
k.crossChainKeeper = &crossChainKeeper
}

// Logger returns a module-specific logger.
func (k Keeper) Logger(ctx sdk.Context) log.Logger {
return ctx.Logger().With("module", "x/"+proposal.ModuleName)
Expand Down
84 changes: 84 additions & 0 deletions x/params/keeper/sync_params.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
package keeper

import (
"encoding/hex"
"math/big"

"github.com/cosmos/cosmos-sdk/bsc/rlp"
unclezoro marked this conversation as resolved.
Show resolved Hide resolved
sdk "github.com/cosmos/cosmos-sdk/types"
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
types "github.com/cosmos/cosmos-sdk/x/params/types/proposal"
)

func (k Keeper) RegisterCrossChainSyncParamsApp() error {
return (*k.crossChainKeeper).RegisterChannel(types.SyncParamsChannel, types.SyncParamsChannelID, k)
}

func (k Keeper) SyncParams(ctx sdk.Context, p *types.ParameterChangeProposal) error {
// this validates content and size of changes is not empty
if err := p.ValidateBasic(); err != nil {
return err
}

unclezoro marked this conversation as resolved.
Show resolved Hide resolved
values := make([]byte, 0)
addresses := make([]byte, 0)

for i, c := range p.Changes {
var value []byte
var err error
if c.Key == types.KeyUpgrade {
value, err = sdk.AccAddressFromHexUnsafe(c.Value)
if err != nil {
return sdkerrors.Wrapf(types.ErrAddressNotValid, "smart contract address is not valid %s", c.Value)
}
} else {
value, err = hex.DecodeString(c.Value)
if err != nil {
return sdkerrors.Wrapf(types.ErrInvalidValue, "value is not valid %s", c.Value)
}
}
values = append(values, value...)
addr, err := sdk.AccAddressFromHexUnsafe(p.Addresses[i])
if err != nil {
return sdkerrors.Wrapf(types.ErrAddressNotValid, "smart contract address is not valid %s", p.Addresses[i])
}
addresses = append(addresses, addr.Bytes()...)
}

pack := types.SyncParamsPackage{
Key: p.Changes[0].Key,
Value: values,
Target: addresses,
}

encodedPackage, err := rlp.EncodeToBytes(pack)
if err != nil {
return sdkerrors.Wrapf(types.ErrInvalidUpgradeProposal, "encode sync params package error")
}
_, err = (*k.crossChainKeeper).CreateRawIBCPackageWithFee(
ctx,
types.SyncParamsChannelID,
sdk.SynCrossChainPackageType,
encodedPackage,
big.NewInt(0),
big.NewInt(0),
)
return err
}

// Need these in order to register paramsKeeper to be a CrosschainApp so that it can register channel(3)

func (k Keeper) ExecuteSynPackage(ctx sdk.Context, appCtx *sdk.CrossChainAppContext, payload []byte) sdk.ExecuteResult {
k.Logger(ctx).Error("received sync params sync package", "payload", hex.EncodeToString(payload))
return sdk.ExecuteResult{}
unclezoro marked this conversation as resolved.
Show resolved Hide resolved
}

func (k Keeper) ExecuteAckPackage(ctx sdk.Context, header *sdk.CrossChainAppContext, payload []byte) sdk.ExecuteResult {
k.Logger(ctx).Error("received sync params in ack package", "payload", hex.EncodeToString(payload))
return sdk.ExecuteResult{}
unclezoro marked this conversation as resolved.
Show resolved Hide resolved
}

func (k Keeper) ExecuteFailAckPackage(ctx sdk.Context, header *sdk.CrossChainAppContext, payload []byte) sdk.ExecuteResult {
k.Logger(ctx).Error("received sync params fail ack package", "payload", hex.EncodeToString(payload))
return sdk.ExecuteResult{}
}
6 changes: 6 additions & 0 deletions x/params/proposal_handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,12 @@ func NewParamChangeProposalHandler(k keeper.Keeper) govtypes.Handler {
}

func handleParameterChangeProposal(ctx sdk.Context, k keeper.Keeper, p *proposal.ParameterChangeProposal) error {
// for govv1.MsgExecLegacyContent, validation is applied by writing to cache Subspace store, since gnfd does not hold
// the subspace for crosschain parameters. the validation is skipped.
if p.CrossChain {
return k.SyncParams(ctx, p)
}

for _, c := range p.Changes {
ss, ok := k.GetSubspace(c.Subspace)
if !ok {
Expand Down
Loading