Skip to content

Commit

Permalink
feat(genesis): add pairs at genesis (#852)
Browse files Browse the repository at this point in the history
* feat(genesis): add pairs at genesis

* update changelog

* move changelog line to Unreleased

* remove line in localnet.sh

Co-authored-by: AgentSmithMatrix <98403347+AgentSmithMatrix@users.noreply.github.com>
Co-authored-by: Agent Smith <agentsmith@matrixsystems.co>
Co-authored-by: Jonathan Gimeno <jgimeno@gmail.com>
  • Loading branch information
4 people authored Aug 28, 2022
1 parent 5b7a78d commit 5851a55
Show file tree
Hide file tree
Showing 5 changed files with 186 additions and 5 deletions.
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## Unreleased

## Features
### Features

* [#852](https://github.com/NibiruChain/nibiru/pull/852) - feat(genesis): add cli command to add pairs at genesis
* [#861](https://github.com/NibiruChain/nibiru/pull/861) - query cumulative funding payments

## v0.14.0
Expand Down
1 change: 1 addition & 0 deletions cmd/nibid/cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,7 @@ func initRootCmd(rootCmd *cobra.Command, encodingConfig params.EncodingConfig) {
AddGenesisAccountCmd(app.DefaultNodeHome),
vpoolcli.AddVPoolGenesisCmd(app.DefaultNodeHome),
pricefeedcli.AddWhitelistGenesisOracle(app.DefaultNodeHome),
pricefeedcli.AddPriceFeedParamPairs(app.DefaultNodeHome),
tmcli.NewCompletionCmd(rootCmd, true),
testnetCmd(app.ModuleBasics, banktypes.GenesisBalancesIterator{}),
debug.Cmd(),
Expand Down
5 changes: 1 addition & 4 deletions scripts/localnet.sh
Original file line number Diff line number Diff line change
Expand Up @@ -195,10 +195,7 @@ add_genesis_param '.app_state.perp.pair_metadata[1].cumulative_premium_fractions

# x/pricefeed
nibid add-genesis-oracle nibi1zaavvzxez0elundtn32qnk9lkm8kmcsz44g7xl
cat $HOME/.nibid/config/genesis.json | jq '.app_state.pricefeed.params.pairs[0] = {token0:"unibi",token1:"unusd"}' > $HOME/.nibid/config/tmp_genesis.json && mv $HOME/.nibid/config/tmp_genesis.json $HOME/.nibid/config/genesis.json
cat $HOME/.nibid/config/genesis.json | jq '.app_state.pricefeed.params.pairs[1] = {token0:"uusdc",token1:"unusd"}' > $HOME/.nibid/config/tmp_genesis.json && mv $HOME/.nibid/config/tmp_genesis.json $HOME/.nibid/config/genesis.json
cat $HOME/.nibid/config/genesis.json | jq '.app_state.pricefeed.params.pairs[2] = {token0:"ubtc",token1:"unusd"}' > $HOME/.nibid/config/tmp_genesis.json && mv $HOME/.nibid/config/tmp_genesis.json $HOME/.nibid/config/genesis.json
cat $HOME/.nibid/config/genesis.json | jq '.app_state.pricefeed.params.pairs[3] = {token0:"ueth",token1:"unusd"}' > $HOME/.nibid/config/tmp_genesis.json && mv $HOME/.nibid/config/tmp_genesis.json $HOME/.nibid/config/genesis.json

cat $HOME/.nibid/config/genesis.json | jq '.app_state.pricefeed.params.twap_lookback_window = "900s"' > $HOME/.nibid/config/tmp_genesis.json && mv $HOME/.nibid/config/tmp_genesis.json $HOME/.nibid/config/genesis.json

# Start the network
Expand Down
96 changes: 96 additions & 0 deletions x/pricefeed/client/cli/gen_param_pair.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
package cli

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

"github.com/cosmos/cosmos-sdk/client"
"github.com/cosmos/cosmos-sdk/client/flags"
"github.com/cosmos/cosmos-sdk/server"
"github.com/cosmos/cosmos-sdk/x/genutil"
genutiltypes "github.com/cosmos/cosmos-sdk/x/genutil/types"
"github.com/spf13/cobra"

"github.com/NibiruChain/nibiru/x/common"
"github.com/NibiruChain/nibiru/x/pricefeed/types"
)

// AddPriceFeedParamPairs returns add-genesis-pricefeed-pairs
func AddPriceFeedParamPairs(defaultNodeHome string) *cobra.Command {
cmd := &cobra.Command{
Use: "add-genesis-pricefeed-pairs [,[pair]]",
Short: "Add pair to genesis.json",
Long: `Adds the pricefeed pairs to genesis.json`,
Args: cobra.ExactArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
clientCtx := client.GetClientContextFromCmd(cmd)
serverCtx := server.GetServerContextFromCmd(cmd)
config := serverCtx.Config

config.SetRoot(clientCtx.HomeDir)

genFile := config.GenesisFile()
appState, genDoc, err := genutiltypes.GenesisStateFromGenFile(genFile)
if err != nil {
return err
}

priceFeed := types.GetGenesisStateFromAppState(clientCtx.Codec, appState)
pairs, err := parseAndValidatePairs(args[0], priceFeed.Params.Pairs)
if err != nil {
return err
}

priceFeed.Params.Pairs = append(priceFeed.Params.Pairs, pairs...)
priceFeedParamsStateBz, err := clientCtx.Codec.MarshalJSON(priceFeed)
if err != nil {
return fmt.Errorf("failed to marshal price feed genesis state: %w", err)
}

appState[types.ModuleName] = priceFeedParamsStateBz
appStateJSON, err := json.Marshal(appState)
if err != nil {
return fmt.Errorf("failed to marshal application genesis state: %w", err)
}

genDoc.AppState = appStateJSON
return genutil.ExportGenesisFile(genDoc, genFile)
},
}

cmd.Flags().String(flags.FlagHome, defaultNodeHome, "The application home directory")
flags.AddQueryFlagsToCmd(cmd)

return cmd
}

func parseAndValidatePairs(pairsStr string, genPairs common.AssetPairs) (common.AssetPairs, error) {
pairs := strings.TrimSpace(pairsStr)
if len(pairs) == 0 {
return nil, fmt.Errorf("no pairs found")
}

pairList := strings.Split(pairs, ",")
newPairs := common.AssetPairs{}
exists := make(map[string]bool)
for _, pair := range pairList {
newPair, err := common.NewAssetPair(pair)
if err != nil {
return nil, err
}

if genPairs.Contains(newPair) {
return nil, fmt.Errorf("pair %s already exists in genesis", pair)
}

if _, found := exists[pair]; found {
return nil, fmt.Errorf("pair %s repeated", pair)
}

newPairs = append(newPairs, newPair)
exists[pair] = true
}

return newPairs, nil
}
86 changes: 86 additions & 0 deletions x/pricefeed/client/cli/gen_param_pair_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
package cli_test

import (
"context"
"fmt"
"testing"

"github.com/cosmos/cosmos-sdk/client"
"github.com/cosmos/cosmos-sdk/client/flags"
"github.com/cosmos/cosmos-sdk/server"
"github.com/cosmos/cosmos-sdk/simapp"
genutiltest "github.com/cosmos/cosmos-sdk/x/genutil/client/testutil"
"github.com/spf13/viper"
"github.com/stretchr/testify/require"
"github.com/tendermint/tendermint/libs/log"

"github.com/NibiruChain/nibiru/x/pricefeed/client/cli"
)

// Tests "add-genesis-pricefeed-pairs", a command that adds pairs to genesis.json
func TestAddPriceFeedParamPair(t *testing.T) {
tests := []struct {
name string
pairName string
expectError bool
}{
{
name: "pair name empty",
pairName: "",
expectError: true,
},
{
name: "invalid pair name",
pairName: "token0:token1:token2:",
expectError: true,
},
{
name: "token name absent",
pairName: "token0:",
expectError: true,
},
{
name: "valid pricefeed pair",
pairName: "token0:token1",
expectError: false,
},
{
name: "valid pricefeed pairs",
pairName: "token0:token1,token3:token4",
expectError: false,
},
}

for _, tc := range tests {
tc := tc
t.Run(tc.name, func(t *testing.T) {
home := t.TempDir()
logger := log.NewNopLogger()
cfg, err := genutiltest.CreateDefaultTendermintConfig(home)
require.NoError(t, err)

appCodec := simapp.MakeTestEncodingConfig().Marshaler
err = genutiltest.ExecInitCmd(
testModuleBasicManager, home, appCodec)
require.NoError(t, err)

serverCtx := server.NewContext(viper.New(), cfg, logger)
clientCtx := client.Context{}.WithCodec(appCodec).WithHomeDir(home)

ctx := context.Background()
ctx = context.WithValue(ctx, client.ClientContextKey, &clientCtx)
ctx = context.WithValue(ctx, server.ServerContextKey, serverCtx)

cmd := cli.AddPriceFeedParamPairs("home")
cmd.SetArgs([]string{
tc.pairName,
fmt.Sprintf("--%s=home", flags.FlagHome)})

if tc.expectError {
require.Error(t, cmd.ExecuteContext(ctx))
} else {
require.NoError(t, cmd.ExecuteContext(ctx))
}
})
}
}

0 comments on commit 5851a55

Please sign in to comment.