diff --git a/.github/workflows/interchaintest.yml b/.github/workflows/interchaintest.yml index f136b26d1..b31ab3c1e 100644 --- a/.github/workflows/interchaintest.yml +++ b/.github/workflows/interchaintest.yml @@ -152,4 +152,8 @@ jobs: ${{ runner.os }}-go- - name: interchaintest - run: make interchaintest-scenario \ No newline at end of file + run: make interchaintest-scenario + + - name: Prune Docker images + if: always() #ensure dangling images are pruned after interchain-test scenario passes or fails + run: docker image prune -f diff --git a/cmd/appstate.go b/cmd/appstate.go index d6378bb8a..5017df85e 100644 --- a/cmd/appstate.go +++ b/cmd/appstate.go @@ -251,3 +251,34 @@ func (a *appState) updatePathConfig( return nil }) } + +func (a *appState) useKey(chainName, key string) error { + + chain, exists := a.config.Chains[chainName] + if !exists { + return fmt.Errorf("chain %s not found in config", chainName) + } + + cc := chain.ChainProvider + + info, err := cc.ListAddresses() + if err != nil { + return err + } + value, exists := info[key] + currentValue := a.config.Chains[chainName].ChainProvider.Key() + + if currentValue == key { + return fmt.Errorf("config is already using %s -> %s for %s", key, value, cc.ChainName()) + } + + if exists { + fmt.Printf("Config will now use %s -> %s for %s\n", key, value, cc.ChainName()) + } else { + return fmt.Errorf("key %s does not exist for chain %s", key, cc.ChainName()) + } + return a.performConfigLockingOperation(context.Background(), func() error { + a.config.Chains[chainName].ChainProvider.UseKey(key) + return nil + }) +} diff --git a/cmd/config.go b/cmd/config.go index 9888a4596..80ae95e4c 100644 --- a/cmd/config.go +++ b/cmd/config.go @@ -395,8 +395,8 @@ func UnmarshalJSONProviderConfig(data []byte, customTypes map[string]reflect.Typ } typeName, ok := m["type"].(string) - if !ok { - return nil, errors.New("cannot find type"); + if !ok { + return nil, errors.New("cannot find type") } var provCfg provider.ProviderConfig diff --git a/cmd/keys.go b/cmd/keys.go index 0ddd447d4..fb09cf46f 100644 --- a/cmd/keys.go +++ b/cmd/keys.go @@ -45,6 +45,7 @@ func keysCmd(a *appState) *cobra.Command { cmd.AddCommand( keysAddCmd(a), + keysUseCmd(a), keysRestoreCmd(a), keysDeleteCmd(a), keysListCmd(a), @@ -55,6 +56,22 @@ func keysCmd(a *appState) *cobra.Command { return cmd } +func keysUseCmd(a *appState) *cobra.Command { + + cmd := &cobra.Command{ + Use: "use chain_name key_name", + Aliases: []string{"a"}, + Short: "Use a key from the keychain associated with a particular chain. Look at ~/.relayer/keys/ibc-0/keyring-test ", + Args: withUsage(cobra.ExactArgs(2)), + Example: strings.TrimSpace(fmt.Sprintf(` +$ %s keys use ibc-0 key_name`, appName)), + RunE: func(cmd *cobra.Command, args []string) error { + return a.useKey(args[0], args[1]) + }, + } + return cmd +} + // keysAddCmd respresents the `keys add` command func keysAddCmd(a *appState) *cobra.Command { cmd := &cobra.Command{ diff --git a/relayer/chains/cosmos/keys.go b/relayer/chains/cosmos/keys.go index 858f77505..ce6c2a2ef 100644 --- a/relayer/chains/cosmos/keys.go +++ b/relayer/chains/cosmos/keys.go @@ -4,6 +4,8 @@ import ( "errors" "os" + "github.com/cosmos/relayer/v2/relayer/provider" + ckeys "github.com/cosmos/cosmos-sdk/client/keys" "github.com/cosmos/cosmos-sdk/crypto/hd" "github.com/cosmos/cosmos-sdk/crypto/keyring" @@ -12,7 +14,6 @@ import ( "github.com/cosmos/relayer/v2/relayer/chains/cosmos/keys/sr25519" "github.com/cosmos/relayer/v2/relayer/codecs/ethermint" "github.com/cosmos/relayer/v2/relayer/codecs/injective" - "github.com/cosmos/relayer/v2/relayer/provider" ) const ethereumCoinType = uint32(60) @@ -69,6 +70,13 @@ func (cc *CosmosProvider) AddKey(name string, coinType uint32, signingAlgorithm return ko, nil } +// Updates config.yaml chain with the specified key. +// It fails config is already using the same key or if the key does not exist +func (cc *CosmosProvider) UseKey(key string) error { + cc.PCfg.Key = key + return nil +} + // RestoreKey converts a mnemonic to a private key and BIP-39 HD Path and persists it to the keystore. // It fails if there is an existing key with the same address. func (cc *CosmosProvider) RestoreKey(name, mnemonic string, coinType uint32, signingAlgorithm string) (address string, err error) { diff --git a/relayer/chains/penumbra/keys.go b/relayer/chains/penumbra/keys.go index aa09fa7b1..0c6131fda 100644 --- a/relayer/chains/penumbra/keys.go +++ b/relayer/chains/penumbra/keys.go @@ -66,6 +66,13 @@ func (cc *PenumbraProvider) AddKey(name string, coinType uint32, signingAlgorith return ko, nil } +// Updates config.yaml chain with the specified key. +// It fails config is already using the same key or if the key does not exist +func (cc *PenumbraProvider) UseKey(key string) error { + cc.PCfg.Key = key + return nil +} + // RestoreKey converts a mnemonic to a private key and BIP-39 HD Path and persists it to the keystore. // It fails if there is an existing key with the same address. func (cc *PenumbraProvider) RestoreKey(name, mnemonic string, coinType uint32, signingAlgorithm string) (address string, err error) { diff --git a/relayer/provider/provider.go b/relayer/provider/provider.go index 34cee434d..2bce8c2c4 100644 --- a/relayer/provider/provider.go +++ b/relayer/provider/provider.go @@ -216,6 +216,7 @@ type KeyProvider interface { CreateKeystore(path string) error KeystoreCreated(path string) bool AddKey(name string, coinType uint32, signingAlgorithm string) (output *KeyOutput, err error) + UseKey(key string) error RestoreKey(name, mnemonic string, coinType uint32, signingAlgorithm string) (address string, err error) ShowAddress(name string) (address string, err error) ListAddresses() (map[string]string, error)