diff --git a/docs/proto/proto-docs.md b/docs/proto/proto-docs.md
index dcd66663..ac8f77bc 100644
--- a/docs/proto/proto-docs.md
+++ b/docs/proto/proto-docs.md
@@ -26,6 +26,8 @@
- [ValidatorAddress](#osmosis.meshsecurity.v1beta1.ValidatorAddress)
- [osmosis/meshsecurity/v1beta1/tx.proto](#osmosis/meshsecurity/v1beta1/tx.proto)
+ - [MsgSetPriceFeedContract](#osmosis.meshsecurity.v1beta1.MsgSetPriceFeedContract)
+ - [MsgSetPriceFeedContractResponse](#osmosis.meshsecurity.v1beta1.MsgSetPriceFeedContractResponse)
- [MsgSetVirtualStakingMaxCap](#osmosis.meshsecurity.v1beta1.MsgSetVirtualStakingMaxCap)
- [MsgSetVirtualStakingMaxCapResponse](#osmosis.meshsecurity.v1beta1.MsgSetVirtualStakingMaxCapResponse)
@@ -287,6 +289,33 @@ ValidatorAddress payload data to be used with the scheduler
+
+
+### MsgSetPriceFeedContract
+MsgSetPriceFeedContract sets the price feed contract to the chain
+to trigger handle epoch task
+
+
+| Field | Type | Label | Description |
+| ----- | ---- | ----- | ----------- |
+| `authority` | [string](#string) | | Authority is the address that controls the module (defaults to x/gov unless overwritten). |
+| `contract` | [string](#string) | | Contract is the address of the price feed smart contract. |
+
+
+
+
+
+
+
+
+### MsgSetPriceFeedContractResponse
+MsgSetPriceFeedContractResponse returns result data.
+
+
+
+
+
+
### MsgSetVirtualStakingMaxCap
@@ -329,6 +358,7 @@ Msg defines the wasm Msg service.
| Method Name | Request Type | Response Type | Description | HTTP Verb | Endpoint |
| ----------- | ------------ | ------------- | ------------| ------- | -------- |
| `SetVirtualStakingMaxCap` | [MsgSetVirtualStakingMaxCap](#osmosis.meshsecurity.v1beta1.MsgSetVirtualStakingMaxCap) | [MsgSetVirtualStakingMaxCapResponse](#osmosis.meshsecurity.v1beta1.MsgSetVirtualStakingMaxCapResponse) | SetVirtualStakingMaxCap creates or updates a maximum cap limit for virtual staking coins | |
+| `SetPriceFeedContract` | [MsgSetPriceFeedContract](#osmosis.meshsecurity.v1beta1.MsgSetPriceFeedContract) | [MsgSetPriceFeedContractResponse](#osmosis.meshsecurity.v1beta1.MsgSetPriceFeedContractResponse) | SetPriceFeedContract sets the price feed contract to the chain to trigger handle epoch task | |
diff --git a/proto/osmosis/meshsecurity/v1beta1/tx.proto b/proto/osmosis/meshsecurity/v1beta1/tx.proto
index 90434bb1..99f88966 100644
--- a/proto/osmosis/meshsecurity/v1beta1/tx.proto
+++ b/proto/osmosis/meshsecurity/v1beta1/tx.proto
@@ -15,6 +15,10 @@ service Msg {
// staking coins
rpc SetVirtualStakingMaxCap(MsgSetVirtualStakingMaxCap)
returns (MsgSetVirtualStakingMaxCapResponse);
+ // SetPriceFeedContract sets the price feed contract to the chain
+ // to trigger handle epoch task
+ rpc SetPriceFeedContract(MsgSetPriceFeedContract)
+ returns (MsgSetPriceFeedContractResponse);
}
// MsgSetVirtualStakingMaxCap creates or updates a maximum cap limit for virtual
@@ -37,3 +41,20 @@ message MsgSetVirtualStakingMaxCap {
// MsgSetVirtualStakingMaxCap returns result data.
message MsgSetVirtualStakingMaxCapResponse {}
+
+// MsgSetPriceFeedContract sets the price feed contract to the chain
+// to trigger handle epoch task
+message MsgSetPriceFeedContract {
+ option (amino.name) = "meshsecurity/MsgSetPriceFeedContract";
+ option (cosmos.msg.v1.signer) = "authority";
+
+ // Authority is the address that controls the module (defaults to x/gov unless
+ // overwritten).
+ string authority = 1;
+
+ // Contract is the address of the price feed smart contract.
+ string contract = 2;
+}
+
+// MsgSetPriceFeedContractResponse returns result data.
+message MsgSetPriceFeedContractResponse {}
diff --git a/scripts/mesh/testibc/config_band.yaml b/scripts/mesh/testibc/config_band.yaml
index 3bfc3dc8..e1f49fb1 100644
--- a/scripts/mesh/testibc/config_band.yaml
+++ b/scripts/mesh/testibc/config_band.yaml
@@ -1,5 +1,5 @@
global:
- api-listen-addr: :5183
+ api-listen-addr: :5184
timeout: 10s
memo: ""
light-cache-size: 20
diff --git a/scripts/mesh/testibc/config_osmosis_local.yaml b/scripts/mesh/testibc/config_osmosis_local.yaml
new file mode 100644
index 00000000..697c40dd
--- /dev/null
+++ b/scripts/mesh/testibc/config_osmosis_local.yaml
@@ -0,0 +1,57 @@
+global:
+ api-listen-addr: :5184
+ timeout: 10s
+ memo: ""
+ light-cache-size: 20
+chains:
+ consumer:
+ type: cosmos
+ value:
+ key-directory: scripts/relayer/keys/chain-1
+ key: key1
+ chain-id: chain-1
+ rpc-addr: http://localhost:26657
+ account-prefix: mesh
+ keyring-backend: test
+ gas-adjustment: 1.2
+ gas-prices: 0.01stake
+ min-gas-amount: 1000000
+ max-gas-amount: 0
+ debug: false
+ timeout: 20s
+ block-timeout: ""
+ output-format: json
+ sign-mode: direct
+ extra-codecs: []
+ coin-type: 118
+ signing-algorithm: ""
+ broadcast-mode: batch
+ min-loop-duration: 0s
+ extension-options: []
+ feegrants: null
+ osmo:
+ type: cosmos
+ value:
+ key-directory: scripts/relayer/keys/osmo
+ key: testnet
+ chain-id: osmo
+ rpc-addr: http://localhost:26677
+ account-prefix: osmo
+ keyring-backend: test
+ gas-adjustment: 1.2
+ gas-prices: 0.005uosmo
+ min-gas-amount: 200000
+ max-gas-amount: 0
+ debug: false
+ timeout: 20s
+ block-timeout: ""
+ output-format: json
+ sign-mode: direct
+ extra-codecs: []
+ coin-type: 118
+ signing-algorithm: ""
+ broadcast-mode: batch
+ min-loop-duration: 0s
+ extension-options: []
+ feegrants: null
+paths: {}
diff --git a/scripts/mesh/testibc/config_osmosis_testnet.yaml b/scripts/mesh/testibc/config_osmosis_testnet.yaml
new file mode 100644
index 00000000..851acf32
--- /dev/null
+++ b/scripts/mesh/testibc/config_osmosis_testnet.yaml
@@ -0,0 +1,57 @@
+global:
+ api-listen-addr: :5184
+ timeout: 10s
+ memo: ""
+ light-cache-size: 20
+chains:
+ consumer:
+ type: cosmos
+ value:
+ key-directory: scripts/relayer/keys/chain-1
+ key: key1
+ chain-id: chain-1
+ rpc-addr: http://localhost:26657
+ account-prefix: mesh
+ keyring-backend: test
+ gas-adjustment: 1.2
+ gas-prices: 0.01stake
+ min-gas-amount: 1000000
+ max-gas-amount: 0
+ debug: false
+ timeout: 20s
+ block-timeout: ""
+ output-format: json
+ sign-mode: direct
+ extra-codecs: []
+ coin-type: 118
+ signing-algorithm: ""
+ broadcast-mode: batch
+ min-loop-duration: 0s
+ extension-options: []
+ feegrants: null
+ osmo:
+ type: cosmos
+ value:
+ key-directory: scripts/relayer/keys/osmo-test-5
+ key: testnet
+ chain-id: osmo-test-5
+ rpc-addr: https://rpc.testnet.osmosis.zone:443
+ account-prefix: osmo
+ keyring-backend: test
+ gas-adjustment: 1.2
+ gas-prices: 0.005uosmo
+ min-gas-amount: 200000
+ max-gas-amount: 0
+ debug: false
+ timeout: 20s
+ block-timeout: ""
+ output-format: json
+ sign-mode: direct
+ extra-codecs: []
+ coin-type: 118
+ signing-algorithm: ""
+ broadcast-mode: batch
+ min-loop-duration: 0s
+ extension-options: []
+ feegrants: null
+paths: {}
diff --git a/scripts/mesh/testibc/osmosis.sh b/scripts/mesh/testibc/osmosis.sh
new file mode 100644
index 00000000..ba0a7352
--- /dev/null
+++ b/scripts/mesh/testibc/osmosis.sh
@@ -0,0 +1,84 @@
+set -xeu
+
+killall osmosisd || true
+sleep 3
+rm -rf $HOME/.osmosisd
+home=$HOME/.osmosisd
+chainid=osmo
+
+osmosisd init localnet --chain-id $chainid --home $home
+
+# Create accounts
+osmosisd keys add val1 --keyring-backend test --home $home
+osmosisd keys add test1 --keyring-backend test --home $home
+
+cat $home/config/genesis.json | jq '.app_state["staking"]["params"]["bond_denom"]="uosmo"' > $home/config/tmp_genesis.json && mv $home/config/tmp_genesis.json $home/config/genesis.json
+
+val1=$(osmosisd keys show val1 --keyring-backend test --home=$home -a)
+test1=$(osmosisd keys show test1 --keyring-backend test --home=$home -a)
+osmosisd add-genesis-account $val1 1000000000000uosmo,10000000000000000000stake --keyring-backend test --home=$home
+osmosisd add-genesis-account $test1 1000000000uosmo --keyring-backend test --home=$home
+
+cat $home/config/genesis.json | jq '.app_state["gov"]["params"]["min_deposit"][0]["denom"]="uosmo"' > $home/config/tmp_genesis.json && mv $home/config/tmp_genesis.json $home/config/genesis.json
+cat $home/config/genesis.json | jq '.app_state["gov"]["params"]["voting_period"]="40s"' > $home/config/tmp_genesis.json && mv $home/config/tmp_genesis.json $home/config/genesis.json
+cat $home/config/genesis.json | jq '.app_state["gov"]["params"]["expedited_voting_period"]="30s"' > $home/config/tmp_genesis.json && mv $home/config/tmp_genesis.json $home/config/genesis.json
+cat $home/config/genesis.json | jq '.app_state["interchainquery"]["params"]["allow_queries"]=["/osmosis.twap.v1beta1.Query/ArithmeticTwapToNow"]' > $home/config/tmp_genesis.json && mv $home/config/tmp_genesis.json $home/config/genesis.json
+
+# update staking genesis
+cat $home/config/genesis.json | jq '.app_state["staking"]["params"]["unbonding_time"]="240s"' > $home/config/tmp_genesis.json && mv $home/config/tmp_genesis.json $home/config/genesis.json
+
+# update crisis variable to uosmo
+cat $home/config/genesis.json | jq '.app_state["crisis"]["constant_fee"]["denom"]="uosmo"' > $home/config/tmp_genesis.json && mv $home/config/tmp_genesis.json $home/config/genesis.json
+
+
+# update epochs genesis
+cat $home/config/genesis.json | jq '.app_state["epochs"]["epochs"][1]["duration"]="60s"' > $home/config/tmp_genesis.json && mv $home/config/tmp_genesis.json $home/config/genesis.json
+
+# update poolincentives genesis
+cat $home/config/genesis.json | jq '.app_state["poolincentives"]["lockable_durations"][0]="120s"' > $home/config/tmp_genesis.json && mv $home/config/tmp_genesis.json $home/config/genesis.json
+cat $home/config/genesis.json | jq '.app_state["poolincentives"]["lockable_durations"][1]="180s"' > $home/config/tmp_genesis.json && mv $home/config/tmp_genesis.json $home/config/genesis.json
+cat $home/config/genesis.json | jq '.app_state["poolincentives"]["lockable_durations"][2]="240s"' > $home/config/tmp_genesis.json && mv $home/config/tmp_genesis.json $home/config/genesis.json
+cat $home/config/genesis.json | jq '.app_state["poolincentives"]["params"]["minted_denom"]="uosmo"' > $home/config/tmp_genesis.json && mv $home/config/tmp_genesis.json $home/config/genesis.json
+
+# update incentives genesis
+cat $home/config/genesis.json | jq '.app_state["incentives"]["lockable_durations"][0]="1s"' > $home/config/tmp_genesis.json && mv $home/config/tmp_genesis.json $home/config/genesis.json
+cat $home/config/genesis.json | jq '.app_state["incentives"]["lockable_durations"][1]="120s"' > $home/config/tmp_genesis.json && mv $home/config/tmp_genesis.json $home/config/genesis.json
+cat $home/config/genesis.json | jq '.app_state["incentives"]["lockable_durations"][2]="180s"' > $home/config/tmp_genesis.json && mv $home/config/tmp_genesis.json $home/config/genesis.json
+cat $home/config/genesis.json | jq '.app_state["incentives"]["lockable_durations"][3]="240s"' > $home/config/tmp_genesis.json && mv $home/config/tmp_genesis.json $home/config/genesis.json
+cat $home/config/genesis.json | jq '.app_state["incentives"]["params"]["distr_epoch_identifier"]="day"' > $home/config/tmp_genesis.json && mv $home/config/tmp_genesis.json $home/config/genesis.json
+
+# update mint genesis
+cat $home/config/genesis.json | jq '.app_state["mint"]["params"]["mint_denom"]="uosmo"' > $home/config/tmp_genesis.json && mv $home/config/tmp_genesis.json $home/config/genesis.json
+cat $home/config/genesis.json | jq '.app_state["mint"]["params"]["epoch_identifier"]="day"' > $home/config/tmp_genesis.json && mv $home/config/tmp_genesis.json $home/config/genesis.json
+
+# update gamm genesis
+cat $home/config/genesis.json | jq '.app_state["gamm"]["params"]["pool_creation_fee"][0]["denom"]="uosmo"' > $home/config/tmp_genesis.json && mv $home/config/tmp_genesis.json $home/config/genesis.json
+
+# update cl genesis
+cat $home/config/genesis.json | jq '.app_state["concentratedliquidity"]["params"]["is_permissionless_pool_creation_enabled"]=true' > $home/config/tmp_genesis.json && mv $home/config/tmp_genesis.json $home/config/genesis.json
+
+cat $home/config/genesis.json | jq '.app_state["txfees"]["basedenom"] = "uosmo"' > $home/config/tmp_genesis.json && mv $home/config/tmp_genesis.json $home/config/genesis.json
+
+osmosisd gentx val1 500000000000uosmo --keyring-backend test --chain-id $chainid --home=$home
+
+osmosisd collect-gentxs --home=$home
+
+VALIDATOR_APP_TOML=$home/config/app.toml
+
+sed -i -E 's|tcp://localhost:1317|tcp://localhost:1337|g' $VALIDATOR_APP_TOML
+sed -i -E 's|localhost:9090|localhost:9290|g' $VALIDATOR_APP_TOML
+sed -i -E 's|localhost:9091|localhost:9291|g' $VALIDATOR_APP_TOML
+sed -i -E 's|tcp://0.0.0.0:10337|tcp://0.0.0.0:12337|g' $VALIDATOR_APP_TOML
+
+VALIDATOR_CONFIG=$home/config/config.toml
+sed -i -E 's|tcp://127.0.0.1:26658|tcp://127.0.0.1:26678|g' $VALIDATOR_CONFIG
+sed -i -E 's|tcp://127.0.0.1:26657|tcp://127.0.0.1:26677|g' $VALIDATOR_CONFIG
+sed -i -E 's|tcp://0.0.0.0:26656|tcp://0.0.0.0:26676|g' $VALIDATOR_CONFIG
+sed -i -E 's|allow_duplicate_ip = false|allow_duplicate_ip = true|g' $VALIDATOR_CONFIG
+
+screen -S osmosis -t osmosis -d -m osmosisd start --home=$home
+
+sleep 10
+osmosisd tx gamm create-pool --pool-file ./scripts/mesh/testibc/pool.json --from val1 --keyring-backend test --node http://localhost:26677 --chain-id osmo --fees 10000uosmo -y --gas auto --gas-adjustment 1.5
+sleep 7
+osmosisd q gamm num-pools --node http://localhost:26677
diff --git a/scripts/mesh/testibc/pool.json b/scripts/mesh/testibc/pool.json
new file mode 100644
index 00000000..c7fc46fe
--- /dev/null
+++ b/scripts/mesh/testibc/pool.json
@@ -0,0 +1,7 @@
+{
+ "weights": "10uosmo,2stake",
+ "initial-deposit": "1000000uosmo,200000stake",
+ "swap-fee": "0.01",
+ "exit-fee": "0",
+ "future-governor": ""
+}
\ No newline at end of file
diff --git a/scripts/mesh/testibc/rly.sh b/scripts/mesh/testibc/rly.sh
index 5ee649a5..4a98b673 100755
--- a/scripts/mesh/testibc/rly.sh
+++ b/scripts/mesh/testibc/rly.sh
@@ -33,6 +33,5 @@ rly tx channel demo --src-port wasm.$converter --dst-port wasm.$ext_staking --or
sleep 5
-echo "abcxyz"
-# screen -S relayer -t relayer -d -m rly start demo
+screen -S relayer -t relayer -d -m rly start demo
sleep 5
\ No newline at end of file
diff --git a/scripts/mesh/testibc/rly_band.sh b/scripts/mesh/testibc/rly_band.sh
index ecdbd12a..b31c77de 100755
--- a/scripts/mesh/testibc/rly_band.sh
+++ b/scripts/mesh/testibc/rly_band.sh
@@ -53,6 +53,7 @@ init_band_price_feed=$(cat < /dev/null && shellcheck "$0"
echo "DEV-only: copy from local built instead of downloading"
-for contract in mesh_external_staking mesh_converter mesh_native_staking mesh_native_staking_proxy mesh_osmosis_price_provider mesh_remote_price_feed mesh_simple_price_feed \
+for contract in mesh_external_staking mesh_converter mesh_native_staking mesh_native_staking_proxy mesh_band_price_feed mesh_osmosis_price_feed mesh_simple_price_feed \
mesh_vault mesh_virtual_staking ; do
cp -f ../../../mesh-security/artifacts/${contract}-aarch64.wasm .
gzip -fk ${contract}-aarch64.wasm
diff --git a/tests/testdata/crosschain_registry.wasm b/tests/testdata/crosschain_registry.wasm
new file mode 100644
index 00000000..cb6a87b2
Binary files /dev/null and b/tests/testdata/crosschain_registry.wasm differ
diff --git a/tests/testdata/mesh_band_price_feed.wasm.gz b/tests/testdata/mesh_band_price_feed.wasm.gz
index 357ec578..2fcbbe12 100644
Binary files a/tests/testdata/mesh_band_price_feed.wasm.gz and b/tests/testdata/mesh_band_price_feed.wasm.gz differ
diff --git a/tests/testdata/mesh_converter.wasm.gz b/tests/testdata/mesh_converter.wasm.gz
index 85925eaf..c92116b6 100644
Binary files a/tests/testdata/mesh_converter.wasm.gz and b/tests/testdata/mesh_converter.wasm.gz differ
diff --git a/tests/testdata/mesh_external_staking.wasm.gz b/tests/testdata/mesh_external_staking.wasm.gz
index 292a1bc6..6e460d93 100644
Binary files a/tests/testdata/mesh_external_staking.wasm.gz and b/tests/testdata/mesh_external_staking.wasm.gz differ
diff --git a/tests/testdata/mesh_native_staking.wasm.gz b/tests/testdata/mesh_native_staking.wasm.gz
index 4ad4a956..9459baa8 100644
Binary files a/tests/testdata/mesh_native_staking.wasm.gz and b/tests/testdata/mesh_native_staking.wasm.gz differ
diff --git a/tests/testdata/mesh_native_staking_proxy.wasm.gz b/tests/testdata/mesh_native_staking_proxy.wasm.gz
index 4a272fcd..855a9501 100644
Binary files a/tests/testdata/mesh_native_staking_proxy.wasm.gz and b/tests/testdata/mesh_native_staking_proxy.wasm.gz differ
diff --git a/tests/testdata/mesh_osmosis_price_feed.wasm.gz b/tests/testdata/mesh_osmosis_price_feed.wasm.gz
index 2250359b..59e2684e 100644
Binary files a/tests/testdata/mesh_osmosis_price_feed.wasm.gz and b/tests/testdata/mesh_osmosis_price_feed.wasm.gz differ
diff --git a/tests/testdata/mesh_osmosis_price_provider.wasm.gz b/tests/testdata/mesh_osmosis_price_provider.wasm.gz
deleted file mode 100644
index cb369462..00000000
Binary files a/tests/testdata/mesh_osmosis_price_provider.wasm.gz and /dev/null differ
diff --git a/tests/testdata/mesh_remote_price_feed.wasm.gz b/tests/testdata/mesh_remote_price_feed.wasm.gz
deleted file mode 100644
index 3dd51fda..00000000
Binary files a/tests/testdata/mesh_remote_price_feed.wasm.gz and /dev/null differ
diff --git a/tests/testdata/mesh_simple_price_feed.wasm.gz b/tests/testdata/mesh_simple_price_feed.wasm.gz
index 6f99efaa..f9d75ebc 100644
Binary files a/tests/testdata/mesh_simple_price_feed.wasm.gz and b/tests/testdata/mesh_simple_price_feed.wasm.gz differ
diff --git a/tests/testdata/mesh_vault.wasm.gz b/tests/testdata/mesh_vault.wasm.gz
index 2a6e5725..8303570b 100644
Binary files a/tests/testdata/mesh_vault.wasm.gz and b/tests/testdata/mesh_vault.wasm.gz differ
diff --git a/tests/testdata/mesh_virtual_staking.wasm.gz b/tests/testdata/mesh_virtual_staking.wasm.gz
index 0bc19308..4e17c3f2 100644
Binary files a/tests/testdata/mesh_virtual_staking.wasm.gz and b/tests/testdata/mesh_virtual_staking.wasm.gz differ
diff --git a/tests/testdata/version.txt b/tests/testdata/version.txt
index 66a6ad6a..10142f3f 100644
--- a/tests/testdata/version.txt
+++ b/tests/testdata/version.txt
@@ -1 +1 @@
-da560f398b59d3a7430efbc1e71cbb0bcf62ad7a
+44c6e65b581a08b5994a86792978f34ce9c51d5d
diff --git a/x/go.mod b/x/go.mod
index 2d1705a0..92a9e45f 100644
--- a/x/go.mod
+++ b/x/go.mod
@@ -37,7 +37,6 @@ require (
github.com/cometbft/cometbft v0.37.2
github.com/cometbft/cometbft-db v0.8.0
google.golang.org/genproto/googleapis/api v0.0.0-20230629202037-9506855d4529
- sigs.k8s.io/yaml v1.3.0
)
require (
@@ -184,6 +183,7 @@ require (
gopkg.in/yaml.v3 v3.0.1 // indirect
nhooyr.io/websocket v1.8.6 // indirect
pgregory.net/rapid v0.5.5 // indirect
+ sigs.k8s.io/yaml v1.3.0 // indirect
)
replace (
diff --git a/x/meshsecurity/client/cli/gov_tx.go b/x/meshsecurity/client/cli/gov_tx.go
index 22186946..2c660ee5 100644
--- a/x/meshsecurity/client/cli/gov_tx.go
+++ b/x/meshsecurity/client/cli/gov_tx.go
@@ -33,6 +33,7 @@ func SubmitProposalCmd() *cobra.Command {
}
cmd.AddCommand(
ProposalSetVirtualStakingMaxCapCmd(),
+ ProposalSetPriceFeedContractCmd(),
)
return cmd
}
@@ -86,6 +87,55 @@ $ %s tx meshsecurity submit-proposal set-virtual-staking-max-cap %s1l94ptufswr6v
return cmd
}
+func ProposalSetPriceFeedContractCmd() *cobra.Command {
+ bech32Prefix := sdk.GetConfig().GetBech32AccountAddrPrefix()
+ cmd := &cobra.Command{
+ Use: "set-price-feed [contract_addr_bech32] --title [text] --summary [text] --authority [address]",
+ Short: "Submit a set virtual staking max cap proposal",
+ Args: cobra.ExactArgs(1),
+ Long: strings.TrimSpace(
+ fmt.Sprintf(`Submit a proposal to set price feed contract to chain.
+
+Example:
+$ %s tx meshsecurity submit-proposal set-price-feed %s1l94ptufswr6v7qntax4m7nvn3jgf6k4gn2rknq --title "a title" --summary "a summary" --authority %s
+`, version.AppName, bech32Prefix, DefaultGovAuthority.String())),
+ RunE: func(cmd *cobra.Command, args []string) error {
+ clientCtx, proposalTitle, summary, metadata, deposit, err := getProposalInfo(cmd)
+ if err != nil {
+ return err
+ }
+ authority, err := cmd.Flags().GetString(flagAuthority)
+ if err != nil {
+ return fmt.Errorf("authority: %s", err)
+ }
+
+ if len(authority) == 0 {
+ return errors.New("authority address is required")
+ }
+
+ src, err := parseSetPriceFeedContractArgs(args, authority)
+ if err != nil {
+ return err
+ }
+
+ proposalMsg, err := v1.NewMsgSubmitProposal([]sdk.Msg{&src}, deposit, clientCtx.GetFromAddress().String(), metadata, proposalTitle, summary)
+ if err != nil {
+ return err
+ }
+ if err = proposalMsg.ValidateBasic(); err != nil {
+ return err
+ }
+
+ return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), proposalMsg)
+ },
+ SilenceUsage: true,
+ }
+
+ // proposal flags
+ addCommonProposalFlags(cmd)
+ return cmd
+}
+
func parseSetVirtualStakingMaxCapArgs(args []string, authority string) (types.MsgSetVirtualStakingMaxCap, error) {
maxCap, err := sdk.ParseCoinNormalized(args[1])
if err != nil {
@@ -100,6 +150,14 @@ func parseSetVirtualStakingMaxCapArgs(args []string, authority string) (types.Ms
return msg, nil
}
+func parseSetPriceFeedContractArgs(args []string, authority string) (types.MsgSetPriceFeedContract, error) {
+ msg := types.MsgSetPriceFeedContract{
+ Authority: authority,
+ Contract: args[0],
+ }
+ return msg, nil
+}
+
func addCommonProposalFlags(cmd *cobra.Command) {
flags.AddTxFlagsToCmd(cmd)
cmd.Flags().String(cli.FlagTitle, "", "Title of proposal")
diff --git a/x/meshsecurity/keeper/msg_server.go b/x/meshsecurity/keeper/msg_server.go
index 1d81decb..412b5a12 100644
--- a/x/meshsecurity/keeper/msg_server.go
+++ b/x/meshsecurity/keeper/msg_server.go
@@ -42,10 +42,35 @@ func (m msgServer) SetVirtualStakingMaxCap(goCtx context.Context, req *types.Msg
return nil, err
}
if !m.k.HasScheduledTask(ctx, types.SchedulerTaskHandleEpoch, acc, true) {
- if err := m.k.ScheduleRegularRebalanceTask(ctx, acc); err != nil {
+ if err := m.k.ScheduleRegularHandleEpochTask(ctx, acc); err != nil {
return nil, errorsmod.Wrap(err, "schedule regular rebalance task")
}
return &types.MsgSetVirtualStakingMaxCapResponse{}, nil
}
return &types.MsgSetVirtualStakingMaxCapResponse{}, nil
}
+
+// SetPriceFeedContract sets the price feed contract to the chain to trigger handle epoch task
+func (m msgServer) SetPriceFeedContract(goCtx context.Context, req *types.MsgSetPriceFeedContract) (*types.MsgSetPriceFeedContractResponse, error) {
+ if err := req.ValidateBasic(); err != nil {
+ return nil, err
+ }
+
+ if authority := m.k.GetAuthority(); authority != req.Authority {
+ return nil, govtypes.ErrInvalidSigner.Wrapf("invalid authority; expected %s, got %s", authority, req.Authority)
+ }
+
+ acc, err := sdk.AccAddressFromBech32(req.Contract)
+ if err != nil {
+ return nil, errorsmod.Wrap(err, "contract")
+ }
+ ctx := sdk.UnwrapSDKContext(goCtx)
+ if !m.k.HasScheduledTask(ctx, types.SchedulerTaskHandleEpoch, acc, true) {
+ if err := m.k.ScheduleRegularHandleEpochTask(ctx, acc); err != nil {
+ return nil, errorsmod.Wrap(err, "schedule regular rebalance task")
+ }
+ return &types.MsgSetPriceFeedContractResponse{}, nil
+ } else {
+ return nil, types.ErrDuplicate
+ }
+}
diff --git a/x/meshsecurity/keeper/msg_server_test.go b/x/meshsecurity/keeper/msg_server_test.go
index 74bd70e8..c56107d4 100644
--- a/x/meshsecurity/keeper/msg_server_test.go
+++ b/x/meshsecurity/keeper/msg_server_test.go
@@ -89,3 +89,76 @@ func TestSetVirtualStakingMaxCap(t *testing.T) {
})
}
}
+
+func TestSetPriceFeedContract(t *testing.T) {
+ pCtx, keepers := CreateDefaultTestInput(t)
+ k := keepers.MeshKeeper
+ myContract := sdk.AccAddress(rand.Bytes(32))
+ denom := keepers.StakingKeeper.BondDenom(pCtx)
+ myAmount := sdk.NewInt64Coin(denom, 123)
+
+ k.wasm = MockWasmKeeper{HasContractInfoFn: func(ctx sdk.Context, contractAddress sdk.AccAddress) bool {
+ return contractAddress.Equals(myContract)
+ }}
+ m := NewMsgServer(k)
+
+ specs := map[string]struct {
+ src types.MsgSetPriceFeedContract
+ setup func(ctx sdk.Context)
+ expErr bool
+ expLimit sdk.Coin
+ expSchedule func(t *testing.T, ctx sdk.Context)
+ }{
+ "limit stored with scheduler for existing contract": {
+ setup: func(ctx sdk.Context) {},
+ src: types.MsgSetPriceFeedContract{
+ Authority: k.GetAuthority(),
+ Contract: myContract.String(),
+ },
+ expLimit: myAmount,
+ expSchedule: func(t *testing.T, ctx sdk.Context) {
+ assert.True(t, k.HasScheduledTask(ctx, types.SchedulerTaskHandleEpoch, myContract, true))
+ },
+ },
+ "fails for non existing contract": {
+ setup: func(ctx sdk.Context) {},
+ src: types.MsgSetPriceFeedContract{
+ Authority: k.GetAuthority(),
+ Contract: sdk.AccAddress(rand.Bytes(32)).String(),
+ },
+ expErr: true,
+ },
+ "unauthorized rejected": {
+ setup: func(ctx sdk.Context) {},
+ src: types.MsgSetPriceFeedContract{
+ Authority: myContract.String(),
+ Contract: myContract.String(),
+ },
+ expErr: true,
+ },
+ "invalid data rejected": {
+ setup: func(ctx sdk.Context) {},
+ src: types.MsgSetPriceFeedContract{},
+ expErr: true,
+ },
+ }
+ for name, spec := range specs {
+ t.Run(name, func(t *testing.T) {
+ ctx, _ := pCtx.CacheContext()
+ spec.setup(ctx)
+
+ // when
+ gotRsp, gotErr := m.SetPriceFeedContract(sdk.WrapSDKContext(ctx), &spec.src)
+
+ // then
+ if spec.expErr {
+ require.Error(t, gotErr)
+ return
+ }
+ require.NoError(t, gotErr)
+ assert.NotNil(t, gotRsp)
+ // and scheduled
+ spec.expSchedule(t, ctx)
+ })
+ }
+}
diff --git a/x/meshsecurity/keeper/scheduler.go b/x/meshsecurity/keeper/scheduler.go
index 194058c2..6fe4ec6d 100644
--- a/x/meshsecurity/keeper/scheduler.go
+++ b/x/meshsecurity/keeper/scheduler.go
@@ -13,8 +13,8 @@ import (
"github.com/osmosis-labs/mesh-security-sdk/x/meshsecurity/types"
)
-// ScheduleRegularRebalanceTask schedule a rebalance task for the given virtual staking contract using params defined epoch length
-func (k Keeper) ScheduleRegularRebalanceTask(ctx sdk.Context, contract sdk.AccAddress) error {
+// ScheduleRegularHandleEpochTask schedule a handle epoch task for the given virtual staking contract using params defined epoch length
+func (k Keeper) ScheduleRegularHandleEpochTask(ctx sdk.Context, contract sdk.AccAddress) error {
if !k.wasm.HasContractInfo(ctx, contract) {
return types.ErrUnknown.Wrapf("contract: %s", contract.String())
}