Skip to content

Commit

Permalink
fix: use multiple execute msg to update fee configs
Browse files Browse the repository at this point in the history
  • Loading branch information
Peartes committed Jan 2, 2025
1 parent df1975c commit 4c4faec
Show file tree
Hide file tree
Showing 6 changed files with 97 additions and 200 deletions.
3 changes: 0 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -295,9 +295,6 @@ test-integration-xion-treasury-grants: compile_integration_tests
@XION_TEST_IMAGE=$(XION_TEST_IMAGE) ./integration_tests/integration_tests.test -test.failfast -test.v -test.run TestTreasuryContract

test-integration-xion-update-treasury-configs: compile_integration_tests
@XION_TEST_IMAGE=$(XION_TEST_IMAGE) ./integration_tests/integration_tests.test -test.failfast -test.v -test.run TestUpdateTreasuryConfigs

test-integration-xion-update-treasury-configs-cli: compile_integration_tests
@XION_TEST_IMAGE=$(XION_TEST_IMAGE) ./integration_tests/integration_tests.test -test.failfast -test.v -test.run TestUpdateTreasuryConfigsWithCLI

test-integration-xion-treasury-multi: compile_integration_tests
Expand Down
Binary file modified integration_tests/testdata/contracts/treasury-aarch64.wasm
Binary file not shown.
18 changes: 8 additions & 10 deletions integration_tests/testdata/unsigned_msgs/fee_configs.json
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
[
{
"description": "Fee allowance for user1",
"allowance": {
"type_url": "/cosmos.feegrant.v1.BasicAllowance",
"value": "CgQICAI="
},
"expiration": 1715151235
}
]
{
"description": "Fee allowance for user1",
"allowance": {
"type_url": "/cosmos.feegrant.v1.BasicAllowance",
"value": "CgQICAI="
},
"expiration": 1715151235
}
153 changes: 5 additions & 148 deletions integration_tests/update_treasury_configs_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,130 +14,6 @@ import (
"github.com/stretchr/testify/require"
)

func TestUpdateTreasuryConfigs(t *testing.T) {
// Setup Xion chain
td := BuildXionChain(t, "0.0uxion", nil)
xion, ctx := td.xionChain, td.ctx

config := types.GetConfig()
config.SetBech32PrefixForAccount("xion", "xionpub")

// Create and fund test user
t.Log("Creating and funding user accounts")
fundAmount := math.NewInt(10_000_000)
users := ibctest.GetAndFundTestUsers(t, ctx, "default", fundAmount, xion)
xionUser := users[0]

err := testutil.WaitForBlocks(ctx, 2, xion)
require.NoError(t, err)

// Deploy contract
t.Log("Deploying contract")
fp, err := os.Getwd()
require.NoError(t, err)

codeIDStr, err := xion.StoreContract(ctx, xionUser.FormattedAddress(),
path.Join(fp, "integration_tests", "testdata", "contracts", "treasury-aarch64.wasm"))
require.NoError(t, err)

// Instantiate contract
t.Log("Instantiating contract")
instantiateMsg := TreasuryInstantiateMsg{
TypeUrls: []string{},
GrantConfigs: []GrantConfig{},
FeeConfig: &FeeConfig{
Description: "test fee grant",
},
}
instantiateMsgStr, err := json.Marshal(instantiateMsg)
require.NoError(t, err)

treasuryAddr, err := xion.InstantiateContract(ctx, xionUser.KeyName(), codeIDStr, string(instantiateMsgStr), true)
require.NoError(t, err)

// Read JSON files for grants and fee configs
t.Log("Reading configuration JSON files")
grantsFile, err := os.ReadFile(path.Join(fp, "integration_tests", "testdata", "unsigned_msgs", "grants.json"))
require.NoError(t, err)

feeConfigsFile, err := os.ReadFile(path.Join(fp, "integration_tests", "testdata", "unsigned_msgs", "fee_configs.json"))
require.NoError(t, err)

var grants []map[string]interface{}
var feeConfigs []FeeConfig
err = json.Unmarshal(grantsFile, &grants)
require.NoError(t, err)

err = json.Unmarshal(feeConfigsFile, &feeConfigs)
require.NoError(t, err)

// Construct update_configs execute message
t.Log("Constructing update_configs message")
executeMsg := map[string]interface{}{
"update_configs": map[string]interface{}{
"grants": grants,
"fee_configs": feeConfigs,
},
}
executeMsgStr, err := json.Marshal(executeMsg)
require.NoError(t, err)

executeCmd := []string{
"wasm", "execute", treasuryAddr, string(executeMsgStr), "--chain-id", xion.Config().ChainID,
}

_, err = ExecTx(t, ctx, xion.GetNode(), xionUser.KeyName(), executeCmd...)
require.NoError(t, err)

// Query and validate Grant Config URLs
t.Log("Querying grant config type URLs")
grantQueryMsg := map[string]interface{}{
"grant_config_type_urls": struct{}{},
}
grantQueryMsgStr, err := json.Marshal(grantQueryMsg)
require.NoError(t, err)

grantQueryRaw, err := ExecQuery(t, ctx, xion.GetNode(), "wasm", "contract-state", "smart", treasuryAddr, string(grantQueryMsgStr))
require.NoError(t, err)

grantQueryBytes, err := json.Marshal(grantQueryRaw["data"])
require.NoError(t, err)

var queriedGrantConfigUrls []string
err = json.Unmarshal(grantQueryBytes, &queriedGrantConfigUrls)
require.NoError(t, err)

// Validate that all grants are in the contract state
require.Equal(t, len(grants), len(queriedGrantConfigUrls))
for _, grant := range grants {
msgTypeURL := grant["msg_type_url"].(string)
require.Contains(t, queriedGrantConfigUrls, msgTypeURL)
}

// Query and validate Fee Config
t.Log("Querying fee config")
feeQueryMsg := map[string]interface{}{
"fee_config": struct{}{},
}
feeQueryMsgStr, err := json.Marshal(feeQueryMsg)
require.NoError(t, err)

feeQueryRaw, err := ExecQuery(t, ctx, xion.GetNode(), "wasm", "contract-state", "smart", treasuryAddr, string(feeQueryMsgStr))
require.NoError(t, err)

feeQueryBytes, err := json.Marshal(feeQueryRaw["data"])
require.NoError(t, err)

var queriedFeeConfig FeeConfig
err = json.Unmarshal(feeQueryBytes, &queriedFeeConfig)
require.NoError(t, err)

// Validate Fee Config
require.Equal(t, len(feeConfigs), 1)
require.Equal(t, feeConfigs[0].Description, queriedFeeConfig.Description)
require.Equal(t, feeConfigs[0].Allowance.TypeURL, queriedFeeConfig.Allowance.TypeURL)
}

func TestUpdateTreasuryConfigsWithCLI(t *testing.T) {
// Setup Xion chain
td := BuildXionChain(t, "0.0uxion", nil)
Expand Down Expand Up @@ -187,30 +63,11 @@ func TestUpdateTreasuryConfigsWithCLI(t *testing.T) {
feeConfigsFile, err := os.CreateTemp("", "*-fee_configs.json")
require.NoError(t, err)

grantsData := []byte(`[
{
"msg_type_url": "/cosmos.bank.v1.MsgSend",
"grant_config": {
"description": "Bank grant",
"authorization": {
"type_url": "/cosmos.authz.v1.GenericAuthorization",
"value": "CgRQYXk="
},
"optional": true
}
}
]`)
grantsData, err := os.ReadFile(path.Join(fp, "integration_tests", "testdata", "unsigned_msgs", "grants.json"))
require.NoError(t, err)

feeConfigsData := []byte(`[
{
"description": "Fee allowance for user1",
"allowance": {
"type_url": "/cosmos.feegrant.v1.BasicAllowance",
"value": "CgQICAI="
},
"expiration": 1715151235
}
]`)
feeConfigsData, err := os.ReadFile(path.Join(fp, "integration_tests", "testdata", "unsigned_msgs", "fee_configs.json"))
require.NoError(t, err)

_, err = grantsFile.Write(grantsData)
require.NoError(t, err)
Expand Down Expand Up @@ -260,7 +117,7 @@ func TestUpdateTreasuryConfigsWithCLI(t *testing.T) {
require.NoError(t, err)

// Validate that all grants are in the contract state
require.Equal(t, 1, len(queriedGrantConfigUrls))
require.Equal(t, 2, len(queriedGrantConfigUrls))
require.Equal(t, "/cosmos.bank.v1.MsgSend", queriedGrantConfigUrls[0])

// Query and validate Fee Config
Expand Down
95 changes: 65 additions & 30 deletions x/xion/client/cli/tx.go
Original file line number Diff line number Diff line change
Expand Up @@ -516,69 +516,104 @@ func NewSignCmd() *cobra.Command {
}

func NewUpdateConfigsCmd() *cobra.Command {
type ExplicitAny struct {
TypeURL string `json:"type_url"`
Value []byte `json:"value"`
}

type GrantConfig struct {
Description string `json:"description"`
Authorization ExplicitAny `json:"authorization"`
Optional bool `json:"optional"`
}

type UpdateGrantConfig struct {
MsgTypeURL string `json:"msg_type_url"`
GrantConfig GrantConfig `json:"grant_config"`
}

type FeeConfig struct {
Description string `json:"description"`
Allowance *ExplicitAny `json:"allowance,omitempty"`
Expiration int32 `json:"expiration,omitempty"`
}
cmd := &cobra.Command{
Use: "update-configs [contract-address] [grants-json-file] [fee-configs-json-file]",
Short: "Update grant and fee configurations in the treasury contract",
Use: "update-configs [contract] [grants_file] [fee_configs_file]",
Short: "Batch update grant configs and fee config for the treasury",
Args: cobra.ExactArgs(3),
RunE: func(cmd *cobra.Command, args []string) error {
clientCtx, err := client.GetClientTxContext(cmd)
if err != nil {
return err
}

// Parse arguments
contractAddress := args[0]
contract := args[0]
grantsFile := args[1]
feeConfigsFile := args[2]

// Read and parse grants JSON file
grantsData, err := os.ReadFile(grantsFile)
if err != nil {
return fmt.Errorf("failed to read grants JSON file: %w", err)
return fmt.Errorf("failed to read grants file: %w", err)
}

var grants []map[string]interface{}
var grants []UpdateGrantConfig
if err := json.Unmarshal(grantsData, &grants); err != nil {
return fmt.Errorf("failed to parse grants JSON file: %w", err)
return fmt.Errorf("failed to unmarshal grants: %w", err)
}

// Read and parse fee configs JSON file
feeConfigsData, err := os.ReadFile(feeConfigsFile)
if err != nil {
return fmt.Errorf("failed to read fee configs JSON file: %w", err)
return fmt.Errorf("failed to read fee configs file: %w", err)
}
var feeConfig FeeConfig
if err := json.Unmarshal(feeConfigsData, &feeConfig); err != nil {
return fmt.Errorf("failed to unmarshal fee configs: %w", err)
}

var feeConfigs []map[string]interface{}
if err := json.Unmarshal(feeConfigsData, &feeConfigs); err != nil {
return fmt.Errorf("failed to parse fee configs JSON file: %w", err)
var msgs []sdk.Msg
for _, grant := range grants {
executeMsg := map[string]interface{}{
"update_grant_config": map[string]interface{}{
"msg_type_url": grant.MsgTypeURL,
"grant_config": grant.GrantConfig,
},
}
msgBz, err := json.Marshal(executeMsg)
if err != nil {
return fmt.Errorf("failed to marshal execute message for grant: %w", err)
}
msg := &wasmtypes.MsgExecuteContract{
Sender: clientCtx.GetFromAddress().String(),
Contract: contract,
Msg: msgBz,
Funds: sdk.Coins{},
}
msgs = append(msgs, msg)
}

// Construct execute message
executeMsg := map[string]interface{}{
"update_configs": map[string]interface{}{
"grants": grants,
"fee_configs": feeConfigs,
feeExecuteMsg := map[string]interface{}{
"update_fee_config": map[string]interface{}{
"fee_config": feeConfig,
},
}

msgBz, err := json.Marshal(executeMsg)
feeMsgBz, err := json.Marshal(feeExecuteMsg)
if err != nil {
return fmt.Errorf("failed to serialize execute message: %w", err)
return fmt.Errorf("failed to marshal execute message for fee config: %w", err)
}

// Create and broadcast transaction
msg := wasmtypes.MsgExecuteContract{
feeMsg := &wasmtypes.MsgExecuteContract{
Sender: clientCtx.GetFromAddress().String(),
Contract: contractAddress,
Msg: msgBz,
Funds: nil,
Contract: contract,
Msg: feeMsgBz,
Funds: sdk.Coins{},
}
msgs = append(msgs, feeMsg)

if err := msg.ValidateBasic(); err != nil {
return err
err = tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msgs...)
if err != nil {
return fmt.Errorf("failed to broadcast transaction: %w", err)
}

return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), &msg)
return nil
},
}

Expand Down
28 changes: 19 additions & 9 deletions x/xion/client/cli/tx_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -219,7 +219,6 @@ func (s *CLITestSuite) TestUpdateConfigsCmd() {
cmd := cli.NewUpdateConfigsCmd()
cmd.SetOutput(io.Discard)

// Prepare mock JSON files for grants and fee configs
grantsFile := "grants.json"
feeConfigsFile := "fee_configs.json"

Expand All @@ -228,17 +227,28 @@ func (s *CLITestSuite) TestUpdateConfigsCmd() {
{
"msg_type_url": "/cosmos.bank.v1.MsgSend",
"grant_config": {
"description": "Bank grant",
"authorization": {
"type_url": "/cosmos.authz.v1.GenericAuthorization",
"value": "CgRQYXk="
},
"optional": true
"description": "Bank grant",
"authorization": {
"type_url": "/cosmos.authz.v1.GenericAuthorization",
"value": "CgRQYXk="
},
"optional": true
}
},
{
"msg_type_url": "/cosmos.staking.v1.MsgDelegate",
"grant_config": {
"description": "Staking grant",
"authorization": {
"type_url": "/cosmos.authz.v1.GenericAuthorization",
"value": "CgREZWxlZ2F0ZQ=="
},
"optional": false
}
}
]`)

feeConfigsData := []byte(`[
feeConfigsData := []byte(`
{
"description": "Fee allowance for user1",
"allowance": {
Expand All @@ -247,7 +257,7 @@ func (s *CLITestSuite) TestUpdateConfigsCmd() {
},
"expiration": 1715151235
}
]`)
`)

require.NoError(s.T(), os.WriteFile(grantsFile, grantsData, 0600))
defer os.Remove(grantsFile)
Expand Down

0 comments on commit 4c4faec

Please sign in to comment.