Skip to content

Commit

Permalink
Merge pull request #520 from CosmWasm/contract_msg_cast
Browse files Browse the repository at this point in the history
Remove json type cast for contract msgs
  • Loading branch information
alpe authored May 25, 2021
2 parents 4631658 + 98431c6 commit 407b965
Show file tree
Hide file tree
Showing 6 changed files with 189 additions and 112 deletions.
4 changes: 2 additions & 2 deletions proto/cosmwasm/wasm/v1beta1/proposal.proto
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ message InstantiateContractProposal {
// Label is optional metadata to be stored with a constract instance.
string label = 6;
// InitMsg json encoded message to be passed to the contract on instantiation
bytes init_msg = 7 [ (gogoproto.casttype) = "encoding/json.RawMessage" ];
bytes init_msg = 7;
// Funds coins that are transferred to the contract on instantiation
repeated cosmos.base.v1beta1.Coin funds = 8 [
(gogoproto.nullable) = false,
Expand All @@ -66,7 +66,7 @@ message MigrateContractProposal {
// CodeID references the new WASM code
uint64 code_id = 5 [ (gogoproto.customname) = "CodeID" ];
// MigrateMsg json encoded message to be passed to the contract on migration
bytes migrate_msg = 6 [ (gogoproto.casttype) = "encoding/json.RawMessage" ];
bytes migrate_msg = 6;
}

// UpdateAdminProposal gov proposal content type to set an admin for a contract.
Expand Down
6 changes: 3 additions & 3 deletions proto/cosmwasm/wasm/v1beta1/tx.proto
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ message MsgInstantiateContract {
// Label is optional metadata to be stored with a contract instance.
string label = 4;
// InitMsg json encoded message to be passed to the contract on instantiation
bytes init_msg = 5 [ (gogoproto.casttype) = "encoding/json.RawMessage" ];
bytes init_msg = 5;
// Funds coins that are transferred to the contract on instantiation
repeated cosmos.base.v1beta1.Coin funds = 6 [
(gogoproto.nullable) = false,
Expand All @@ -80,7 +80,7 @@ message MsgExecuteContract {
// Contract is the address of the smart contract
string contract = 2;
// Msg json encoded message to be passed to the contract
bytes msg = 3 [ (gogoproto.casttype) = "encoding/json.RawMessage" ];
bytes msg = 3;
// Funds coins that are transferred to the contract on execution
repeated cosmos.base.v1beta1.Coin funds = 5 [
(gogoproto.nullable) = false,
Expand All @@ -103,7 +103,7 @@ message MsgMigrateContract {
// CodeID references the new WASM code
uint64 code_id = 3 [ (gogoproto.customname) = "CodeID" ];
// MigrateMsg json encoded message to be passed to the contract on migration
bytes migrate_msg = 4 [ (gogoproto.casttype) = "encoding/json.RawMessage" ];
bytes migrate_msg = 4;
}

// MsgMigrateContractResponse returns contract migration result data.
Expand Down
9 changes: 8 additions & 1 deletion x/wasm/types/proposal.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package types

import (
"encoding/base64"
"encoding/json"
"fmt"
"strings"

Expand Down Expand Up @@ -184,8 +185,11 @@ func (p InstantiateContractProposal) ValidateBasic() error {
return err
}
}
return nil
if !json.Valid(p.InitMsg) {
return sdkerrors.Wrap(ErrInvalid, "init msg json")
}

return nil
}

// String implements the Stringer interface.
Expand Down Expand Up @@ -251,6 +255,9 @@ func (p MigrateContractProposal) ValidateBasic() error {
if _, err := sdk.AccAddressFromBech32(p.RunAs); err != nil {
return sdkerrors.Wrap(err, "run as")
}
if !json.Valid(p.MigrateMsg) {
return sdkerrors.Wrap(ErrInvalid, "migrate msg json")
}
return nil
}

Expand Down
98 changes: 48 additions & 50 deletions x/wasm/types/proposal.pb.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

75 changes: 75 additions & 0 deletions x/wasm/types/proposal_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package types

import (
"bytes"
"encoding/json"
"strings"
"testing"

Expand Down Expand Up @@ -199,6 +200,13 @@ func TestValidateInstantiateContractProposal(t *testing.T) {
src: InstantiateContractProposalFixture(func(p *InstantiateContractProposal) {
p.InitMsg = nil
}),
expErr: true,
},
"with invalid init msg": {
src: InstantiateContractProposalFixture(func(p *InstantiateContractProposal) {
p.InitMsg = []byte("not a json string")
}),
expErr: true,
},
"without init funds": {
src: InstantiateContractProposalFixture(func(p *InstantiateContractProposal) {
Expand Down Expand Up @@ -282,6 +290,13 @@ func TestValidateMigrateContractProposal(t *testing.T) {
src: MigrateContractProposalFixture(func(p *MigrateContractProposal) {
p.MigrateMsg = nil
}),
expErr: true,
},
"migrate msg with invalid json": {
src: MigrateContractProposalFixture(func(p *MigrateContractProposal) {
p.MigrateMsg = []byte("not a json message")
}),
expErr: true,
},
"base data missing": {
src: MigrateContractProposalFixture(func(p *MigrateContractProposal) {
Expand Down Expand Up @@ -695,3 +710,63 @@ func TestConvertToProposals(t *testing.T) {
})
}
}

func TestUnmarshalContentFromJson(t *testing.T) {
specs := map[string]struct {
src string
got govtypes.Content
exp govtypes.Content
}{
"instantiate ": {
src: `
{
"title": "foo",
"description": "bar",
"admin": "myAdminAddress",
"code_id": 1,
"funds": [{"denom": "ALX", "amount": "2"},{"denom": "BLX","amount": "3"}],
"init_msg": "e30=",
"label": "testing",
"run_as": "myRunAsAddress"
}`,
got: &InstantiateContractProposal{},
exp: &InstantiateContractProposal{
Title: "foo",
Description: "bar",
RunAs: "myRunAsAddress",
Admin: "myAdminAddress",
CodeID: 1,
Label: "testing",
InitMsg: []byte("{}"),
Funds: sdk.NewCoins(sdk.NewCoin("ALX", sdk.NewInt(2)), sdk.NewCoin("BLX", sdk.NewInt(3))),
},
},
"migrate ": {
src: `
{
"title": "foo",
"description": "bar",
"code_id": 1,
"contract": "myContractAddr",
"migrate_msg": "e30=",
"run_as": "myRunAsAddress"
}`,
got: &MigrateContractProposal{},
exp: &MigrateContractProposal{
Title: "foo",
Description: "bar",
RunAs: "myRunAsAddress",
Contract: "myContractAddr",
CodeID: 1,
MigrateMsg: []byte("{}"),
},
},
}
for name, spec := range specs {
t.Run(name, func(t *testing.T) {
require.NoError(t, json.Unmarshal([]byte(spec.src), spec.got))
assert.Equal(t, spec.exp, spec.got)
})
}

}
Loading

0 comments on commit 407b965

Please sign in to comment.