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(oracle): update params #83

Merged
merged 17 commits into from
Jul 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions x/oracle/client/cli/tx.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ func GetTxCmd() *cobra.Command {
}

cmd.AddCommand(CmdCreatePrice())
cmd.AddCommand(CmdUpdateParams())
// this line is used by starport scaffolding # 1

return cmd
Expand Down
3 changes: 1 addition & 2 deletions x/oracle/client/cli/tx_create_price.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,7 @@ func CmdCreatePrice() *cobra.Command {
// TODO: support v1 single sourceID for temporary
Use: "create-price feederid basedblock nonce sourceid decimal price timestamp detid optinoal(price timestamp detid) optional(desc)",
Short: "Broadcast message create-price",
// Args: cobra.ExactArgs(0),
Args: cobra.MinimumNArgs(8),
Args: cobra.MinimumNArgs(8),
RunE: func(cmd *cobra.Command, args []string) (err error) {
clientCtx, err := client.GetClientTxContext(cmd)
if err != nil {
Expand Down
33 changes: 33 additions & 0 deletions x/oracle/client/cli/tx_update_params.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package cli

import (
"github.com/ExocoreNetwork/exocore/x/oracle/types"
"github.com/cosmos/cosmos-sdk/client"
"github.com/cosmos/cosmos-sdk/client/flags"
"github.com/cosmos/cosmos-sdk/client/tx"
"github.com/spf13/cobra"
)

func CmdUpdateParams() *cobra.Command {
cmd := &cobra.Command{
// TODO: support v1 single sourceID for temporary
Use: "update-params params",
Short: "Broadcast message update-params",
Args: cobra.MinimumNArgs(1),
RunE: func(cmd *cobra.Command, args []string) (err error) {
clientCtx, err := client.GetClientTxContext(cmd)
if err != nil {
return err
}
msg := types.NewMsgUpdateParams(clientCtx.GetFromAddress().String(), args[0])
if err := msg.ValidateBasic(); err != nil {
return err
}
return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msg)
},
}

flags.AddTxFlagsToCmd(cmd)

return cmd
}
2 changes: 1 addition & 1 deletion x/oracle/keeper/keeper.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ type (
storeKey storetypes.StoreKey
memKey storetypes.StoreKey
paramstore paramtypes.Subspace
authority string
// authority string
common.KeeperDogfood
}
)
Expand Down
47 changes: 40 additions & 7 deletions x/oracle/keeper/msg_server_update_params.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,51 @@ import (

"github.com/ExocoreNetwork/exocore/x/oracle/types"
sdk "github.com/cosmos/cosmos-sdk/types"
govtypes "github.com/cosmos/cosmos-sdk/x/gov/types"
)

func (ms msgServer) UpdateParams(goCtx context.Context, msg *types.MsgUpdateParams) (*types.MsgUpdateParamsResponse, error) {
ctx := sdk.UnwrapSDKContext(goCtx)

if ms.authority != msg.Authority {
return nil, govtypes.ErrInvalidSigner.Wrapf("invalid authority; expected %s, got %s", ms.authority, msg.Authority)
}

// store params
ms.SetParams(ctx, msg.Params)
// TODO: skip the authority check for test
// if ms.authority != msg.Authority {
// return nil, govtypes.ErrInvalidSigner.Wrapf("invalid authority; expected %s, got %s", ms.authority, msg.Authority)
// }
Comment on lines +13 to +16
Copy link
Contributor

Choose a reason for hiding this comment

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

Tip

Codebase Verification

Consider security implications of the commented-out authority check.

The authority check is still commented out in the file x/oracle/keeper/msg_server_update_params.go. It's crucial to ensure this is re-enabled in production to prevent unauthorized updates to parameters.

  • File: x/oracle/keeper/msg_server_update_params.go
  • Lines: 13-16
Analysis chain

Consider security implications of the commented-out authority check.

The authority check is commented out with a TODO note for testing purposes. It's crucial to ensure this is re-enabled in production to prevent unauthorized updates to parameters.

Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify if the authority check is re-enabled in production.

# Test: Search for the authority check in production branch. Expect: Authority check should be present.
rg --type go 'ms.authority != msg.Authority' --exec cat {}

Length of output: 471


Script:

#!/bin/bash
# Description: Verify if the authority check is re-enabled in production.

# Test: Search for the authority check in the codebase. Expect: Authority check should be present.
rg --type go 'ms.authority != msg.Authority'

Length of output: 129


p := ms.GetParams(ctx)
var err error
defer func() {
if err != nil {
ms.Logger(ctx).Error("UpdateParams failed", "error", err)
}
}()
height := uint64(ctx.BlockHeight())
// add sources
if p, err = p.AddSources(msg.Params.Sources...); err != nil {
return nil, err
}
// add chains
if p, err = p.AddChains(msg.Params.Chains...); err != nil {
return nil, err
}
// add tokens
if p, err = p.UpdateTokens(height, msg.Params.Tokens...); err != nil {
return nil, err
}
// add rules
if p, err = p.AddRules(msg.Params.Rules...); err != nil {
return nil, err
}
// udpate tokenFeeders
for _, tokenFeeder := range msg.Params.TokenFeeders {
if p, err = p.UpdateTokenFeeder(tokenFeeder, height); err != nil {
return nil, err
}
}
// validate params
if err = p.Validate(); err != nil {
return nil, err
}
// set updated new params
ms.SetParams(ctx, p)
return &types.MsgUpdateParamsResponse{}, nil
}
155 changes: 155 additions & 0 deletions x/oracle/keeper/msg_server_update_params_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
package keeper_test

import (
"github.com/ExocoreNetwork/exocore/x/oracle/types"
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
)

var _ = Describe("MsgUpdateParams", func() {
var defaultParams types.Params
BeforeEach(func() {
ks.Reset()
Expect(ks.ms).ToNot(BeNil())
defaultParams = ks.k.GetParams(ks.ctx)
})

Context("Update Chains", func() {
inputAddChains := []string{
`{"chains":[{"name":"Bitcoin", "desc":"-"}]}`,
`{"chains":[{"name":"Ethereum", "desc":"-"}]}`,
}
It("add chain with new name", func() {
msg := types.NewMsgUpdateParams("", inputAddChains[0])
_, err := ks.ms.UpdateParams(ks.ctx, msg)
Expect(err).Should(BeNil())
p := ks.k.GetParams(ks.ctx)
Expect(p.Chains[2].Name).Should(BeEquivalentTo("Bitcoin"))

})
It("add chain with duplicated name", func() {
_, err := ks.ms.UpdateParams(ks.ctx, types.NewMsgUpdateParams("", inputAddChains[1]))
Expect(err).Should(MatchError(types.ErrInvalidParams.Wrap("invalid source to add, duplicated")))
})
})
Context("Update Sources", func() {
inputAddSources := []string{
`{"sources":[{"name":"CoinGecko", "desc":"-", "valid":true}]}`,
`{"sources":[{"name":"CoinGecko", "desc":"-"}]}`,
`{"sources":[{"name":"Chainlink", "desc":"-", "valid":true}]}`,
}
It("add valid source with new name", func() {
_, err := ks.ms.UpdateParams(ks.ctx, types.NewMsgUpdateParams("", inputAddSources[0]))
Expect(err).Should(BeNil())
p := ks.k.GetParams(ks.ctx)
Expect(p.Sources[2].Name).Should(BeEquivalentTo("CoinGecko"))
})
It("add invalid source with new name", func() {
_, err := ks.ms.UpdateParams(ks.ctx, types.NewMsgUpdateParams("", inputAddSources[1]))
Expect(err).Should(MatchError(types.ErrInvalidParams.Wrap("invalid source to add, new source should be valid")))
})
It("add source with duplicated name", func() {
_, err := ks.ms.UpdateParams(ks.ctx, types.NewMsgUpdateParams("", inputAddSources[2]))
Expect(err).Should(MatchError(types.ErrInvalidParams.Wrap("invalid source to add, duplicated")))
})
})
Context("Update Tokens", func() {
startBasedBlocks := []uint64{1, 3, 3, 3, 1, 1, 1}
inputUpdateTokens := []string{
`{"tokens":[{"name":"UNI", "chain_id":"1"}]}`,
`{"tokens":[{"name":"ETH", "chain_id":"1", "decimal":8}]}`,
`{"tokens":[{"name":"ETH", "chain_id":"1", "asset_id":"assetID"}]}`,
`{"tokens":[{"name":"ETH", "chain_id":"1", "contract_address":"contractAddress"}]}`,
`{"tokens":[{"name":"ETH", "chain_id":"1", "decimal":8}]}`,
`{"tokens":[{"name":"ETH", "chain_id":"0"}]}`,
`{"tokens":[{"name":"ETH", "chain_id":"3"}]}`,
}
errs := []error{
nil,
nil,
nil,
nil,
nil,
types.ErrInvalidParams.Wrap("invalid token to add, chain not found"),
types.ErrInvalidParams.Wrap("invalid token to add, chain not found"),
}
token := types.DefaultParams().Tokens[1]
token1 := *token
token1.Decimal = 8

token2 := *token
token2.AssetID = "assetID"

token3 := *token
token3.ContractAddress = "0x123"

updatedTokenETH := []*types.Token{
nil,
&token1,
&token2,
&token3,
token,
nil,
nil,
}

for i, input := range inputUpdateTokens {
It("", func() { //})
if startBasedBlocks[i] > 1 {
p := defaultParams
p.TokenFeeders[1].StartBaseBlock = startBasedBlocks[i]
ks.k.SetParams(ks.ctx, p)
}
_, err := ks.ms.UpdateParams(ks.ctx, types.NewMsgUpdateParams("", input))
if errs[i] == nil {
Expect(err).Should(BeNil())
} else {
Expect(err).Should(MatchError(errs[i]))
}
if updatedTokenETH[i] != nil {
p := ks.k.GetParams(ks.ctx)
Expect(p.Tokens[1]).Should(BeEquivalentTo(updatedTokenETH[i]))
}
})
}

})

Context("", func() {
It("update StartBaseBlock for TokenFeeder", func() {
p := defaultParams
p.TokenFeeders[1].StartBaseBlock = 10
ks.k.SetParams(ks.ctx, p)
p.TokenFeeders[1].StartBaseBlock = 5
_, err := ks.ms.UpdateParams(ks.ctx, &types.MsgUpdateParams{
Params: types.Params{
TokenFeeders: []*types.TokenFeeder{
{
TokenID: 1,
StartBaseBlock: 5,
},
},
},
})
Expect(err).Should(BeNil())
p = ks.k.GetParams(ks.ctx)
Expect(p.TokenFeeders[1].StartBaseBlock).Should(BeEquivalentTo(5))
})
It("Add AssetID for Token", func() {
_, err := ks.ms.UpdateParams(ks.ctx, &types.MsgUpdateParams{
Params: types.Params{
Tokens: []*types.Token{
{
Name: "ETH",
ChainID: 1,
AssetID: "0x83e6850591425e3c1e263c054f4466838b9bd9e4_0x9ce1",
},
},
},
})
Expect(err).Should(BeNil())
p := ks.k.GetParams(ks.ctx)
Expect(p.Tokens[1].AssetID).Should(BeEquivalentTo("0x83e6850591425e3c1e263c054f4466838b9bd9e4_0x9ce1"))
})
})
})
Loading
Loading