Repository: cosmos/relayer
Pull request #1134 (2023-03-21 22:33:10)

fix default coin type
Allow backwards compatibility with previous cosmos provider configs which do not have `coin-type` and chains in the chain-registry which do not have `slip44`. If the config field is not present, the default value of 118 will be used.


Patch:
diff --git a/cmd/keys.go b/cmd/keys.go
index 36072d4..bcf1c56 100644
--- a/cmd/keys.go
+++ b/cmd/keys.go
@@ -81,8 +81,8 @@ $ %s k a cosmoshub testkey`, appName, appName, appName)),
 			}
 
 			if coinType < 0 {
-				if ccp, ok := chain.ChainProvider.(*cosmos.CosmosProvider); ok {
-					coinType = int32(ccp.PCfg.Slip44)
+				if ccp, ok := chain.ChainProvider.(*cosmos.CosmosProvider); ok && ccp.PCfg.Slip44 != nil {
+					coinType = int32(*ccp.PCfg.Slip44)
 				} else {
 					coinType = int32(defaultCoinType)
 				}
@@ -135,8 +135,8 @@ $ %s k r cosmoshub faucet-key "[mnemonic-words]"`, appName, appName)),
 			}
 
 			if coinType < 0 {
-				if ccp, ok := chain.ChainProvider.(*cosmos.CosmosProvider); ok {
-					coinType = int32(ccp.PCfg.Slip44)
+				if ccp, ok := chain.ChainProvider.(*cosmos.CosmosProvider); ok && ccp.PCfg.Slip44 != nil {
+					coinType = int32(*ccp.PCfg.Slip44)
 				} else {
 					coinType = int32(defaultCoinType)
 				}
diff --git a/cregistry/chain_info.go b/cregistry/chain_info.go
index 7cea1cb..978142f 100644
--- a/cregistry/chain_info.go
+++ b/cregistry/chain_info.go
@@ -55,7 +55,7 @@ type ChainInfo struct {
 	Genesis      struct {
 		GenesisURL string `json:"genesis_url"`
 	} `json:"genesis"`
-	Slip44   int `json:"slip44"`
+	Slip44   *int `json:"slip44"`
 	Codebase struct {
 		GitRepo            string   `json:"git_repo"`
 		RecommendedVersion string   `json:"recommended_version"`
diff --git a/relayer/chains/cosmos/provider.go b/relayer/chains/cosmos/provider.go
index b56bcdc..f34ec57 100644
--- a/relayer/chains/cosmos/provider.go
+++ b/relayer/chains/cosmos/provider.go
@@ -52,7 +52,7 @@ type CosmosProviderConfig struct {
 	SignModeStr    string                  `json:"sign-mode" yaml:"sign-mode"`
 	ExtraCodecs    []string                `json:"extra-codecs" yaml:"extra-codecs"`
 	Modules        []module.AppModuleBasic `json:"-" yaml:"-"`
-	Slip44         int                     `json:"coin-type" yaml:"coin-type"`
+	Slip44         *int                    `json:"coin-type" yaml:"coin-type"`
 	Broadcast      provider.BroadcastMode  `json:"broadcast-mode" yaml:"broadcast-mode"`
 }
 


Test patch:
diff --git a/cmd/keys_test.go b/cmd/keys_test.go
index 6a302fd..df51f89 100644
--- a/cmd/keys_test.go
+++ b/cmd/keys_test.go
@@ -42,6 +42,8 @@ func TestKeysRestore_Delete(t *testing.T) {
 
 	_ = sys.MustRun(t, "config", "init")
 
+	slip44 := 118
+
 	sys.MustAddChain(t, "testChain", cmd.ProviderConfigWrapper{
 		Type: "cosmos",
 		Value: cosmos.CosmosProviderConfig{
@@ -49,7 +51,7 @@ func TestKeysRestore_Delete(t *testing.T) {
 			ChainID:        "testcosmos",
 			KeyringBackend: "test",
 			Timeout:        "10s",
-			Slip44:         118,
+			Slip44:         &slip44,
 		},
 	})
 
@@ -82,6 +84,8 @@ func TestKeysExport(t *testing.T) {
 
 	_ = sys.MustRun(t, "config", "init")
 
+	slip44 := 118
+
 	sys.MustAddChain(t, "testChain", cmd.ProviderConfigWrapper{
 		Type: "cosmos",
 		Value: cosmos.CosmosProviderConfig{
@@ -89,7 +93,7 @@ func TestKeysExport(t *testing.T) {
 			ChainID:        "testcosmos",
 			KeyringBackend: "test",
 			Timeout:        "10s",
-			Slip44:         118,
+			Slip44:         &slip44,
 		},
 	})
 
@@ -113,3 +117,68 @@ func TestKeysExport(t *testing.T) {
 
 	// TODO: confirm the imported address matches?
 }
+
+func TestKeysDefaultCoinType(t *testing.T) {
+	t.Parallel()
+
+	sys := relayertest.NewSystem(t)
+
+	_ = sys.MustRun(t, "config", "init")
+
+	slip44 := 118
+
+	sys.MustAddChain(t, "testChain", cmd.ProviderConfigWrapper{
+		Type: "cosmos",
+		Value: cosmos.CosmosProviderConfig{
+			AccountPrefix:  "cosmos",
+			ChainID:        "testcosmos-1",
+			KeyringBackend: "test",
+			Timeout:        "10s",
+			Slip44:         &slip44,
+		},
+	})
+
+	sys.MustAddChain(t, "testChain2", cmd.ProviderConfigWrapper{
+		Type: "cosmos",
+		Value: cosmos.CosmosProviderConfig{
+			AccountPrefix:  "cosmos",
+			ChainID:        "testcosmos-2",
+			KeyringBackend: "test",
+			Timeout:        "10s",
+		},
+	})
+
+	// Restore a key with mnemonic to the chain.
+	res := sys.MustRun(t, "keys", "restore", "testChain", "default", relayertest.ZeroMnemonic)
+	require.Equal(t, res.Stdout.String(), relayertest.ZeroCosmosAddr+"\n")
+	require.Empty(t, res.Stderr.String())
+
+	// Restore a key with mnemonic to the chain.
+	res = sys.MustRun(t, "keys", "restore", "testChain2", "default", relayertest.ZeroMnemonic)
+	require.Equal(t, res.Stdout.String(), relayertest.ZeroCosmosAddr+"\n")
+	require.Empty(t, res.Stderr.String())
+
+	// Export the key.
+	res = sys.MustRun(t, "keys", "export", "testChain", "default")
+	armorOut := res.Stdout.String()
+	require.Contains(t, armorOut, "BEGIN TENDERMINT PRIVATE KEY")
+	require.Empty(t, res.Stderr.String())
+
+	// Export the key.
+	res = sys.MustRun(t, "keys", "export", "testChain2", "default")
+	armorOut2 := res.Stdout.String()
+	require.Contains(t, armorOut, "BEGIN TENDERMINT PRIVATE KEY")
+	require.Empty(t, res.Stderr.String())
+
+	// Import the key to a temporary keyring.
+	registry := codectypes.NewInterfaceRegistry()
+	cryptocodec.RegisterInterfaces(registry)
+	cdc := codec.NewProtoCodec(registry)
+	kr := keyring.NewInMemory(cdc)
+	require.NoError(t, kr.ImportPrivKey("temp", armorOut, keys.DefaultKeyPass))
+
+	// This should fail due to same key
+	err := kr.ImportPrivKey("temp", armorOut2, keys.DefaultKeyPass)
+	require.Error(t, err, "same key was able to be imported twice")
+	require.Contains(t, err.Error(), "cannot overwrite key")
+}