Skip to content

Commit

Permalink
Fix price feed
Browse files Browse the repository at this point in the history
  • Loading branch information
trinitys7 committed Oct 28, 2024
1 parent 4d177ba commit 3558f3c
Show file tree
Hide file tree
Showing 19 changed files with 216 additions and 9 deletions.
30 changes: 30 additions & 0 deletions docs/proto/proto-docs.md
Original file line number Diff line number Diff line change
Expand Up @@ -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)

Expand Down Expand Up @@ -287,6 +289,33 @@ ValidatorAddress payload data to be used with the scheduler



<a name="osmosis.meshsecurity.v1beta1.MsgSetPriceFeedContract"></a>

### 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. |






<a name="osmosis.meshsecurity.v1beta1.MsgSetPriceFeedContractResponse"></a>

### MsgSetPriceFeedContractResponse
MsgSetPriceFeedContractResponse returns result data.






<a name="osmosis.meshsecurity.v1beta1.MsgSetVirtualStakingMaxCap"></a>

### MsgSetVirtualStakingMaxCap
Expand Down Expand Up @@ -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 | |

<!-- end services -->

Expand Down
21 changes: 21 additions & 0 deletions proto/osmosis/meshsecurity/v1beta1/tx.proto
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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 {}
3 changes: 1 addition & 2 deletions scripts/mesh/testibc/rly.sh
Original file line number Diff line number Diff line change
Expand Up @@ -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
5 changes: 3 additions & 2 deletions scripts/mesh/testibc/rly_band.sh
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ init_band_price_feed=$(cat <<EOF
"prepare_gas": "40000",
"execute_gas": "300000",
"minimum_sources": 2,
"epoch_in_secs": 30,
"price_info_ttl_in_secs": 60
}
EOF
Expand All @@ -66,7 +67,7 @@ echo "price feed contract: $price_feed"

rly tx channel demo-band --src-port wasm.$price_feed --dst-port oracle --order unordered --version bandchain-1 --home ./scripts/relayer --override

sleep 5
sleep 7

screen -S relayer -t relayer -d -m rly start demo-band --home ./scripts/relayer
screen -S relayer-band -t relayer-band -d -m rly start demo-band --home ./scripts/relayer
sleep 5
2 changes: 1 addition & 1 deletion tests/testdata/copy_local_wasm_aarch64.sh
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ command -v shellcheck > /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_osmosis_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
Expand Down
Binary file modified tests/testdata/mesh_band_price_feed.wasm.gz
Binary file not shown.
Binary file modified tests/testdata/mesh_converter.wasm.gz
Binary file not shown.
Binary file modified tests/testdata/mesh_external_staking.wasm.gz
Binary file not shown.
Binary file modified tests/testdata/mesh_native_staking.wasm.gz
Binary file not shown.
Binary file modified tests/testdata/mesh_native_staking_proxy.wasm.gz
Binary file not shown.
Binary file modified tests/testdata/mesh_osmosis_price_feed.wasm.gz
Binary file not shown.
Binary file modified tests/testdata/mesh_simple_price_feed.wasm.gz
Binary file not shown.
Binary file modified tests/testdata/mesh_vault.wasm.gz
Binary file not shown.
Binary file modified tests/testdata/mesh_virtual_staking.wasm.gz
Binary file not shown.
2 changes: 1 addition & 1 deletion tests/testdata/version.txt
Original file line number Diff line number Diff line change
@@ -1 +1 @@
1c1f84d56570fda573ba3aa56263e2e01be12c57
44c6e65b581a08b5994a86792978f34ce9c51d5d
58 changes: 58 additions & 0 deletions x/meshsecurity/client/cli/gov_tx.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ func SubmitProposalCmd() *cobra.Command {
}
cmd.AddCommand(
ProposalSetVirtualStakingMaxCapCmd(),
ProposalSetPriceFeedContractCmd(),
)
return cmd
}
Expand Down Expand Up @@ -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 {
Expand All @@ -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")
Expand Down
27 changes: 26 additions & 1 deletion x/meshsecurity/keeper/msg_server.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
}
73 changes: 73 additions & 0 deletions x/meshsecurity/keeper/msg_server_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
})
}
}
4 changes: 2 additions & 2 deletions x/meshsecurity/keeper/scheduler.go
Original file line number Diff line number Diff line change
Expand Up @@ -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())
}
Expand Down

0 comments on commit 3558f3c

Please sign in to comment.