-
Notifications
You must be signed in to change notification settings - Fork 202
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(genesis): add pairs at genesis (#852)
* 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
1 parent
5b7a78d
commit 5851a55
Showing
5 changed files
with
186 additions
and
5 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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)) | ||
} | ||
}) | ||
} | ||
} |