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(client,simapp): inject keyring in autocli opts #17351

Merged
merged 13 commits into from
Aug 14, 2023
2 changes: 1 addition & 1 deletion client/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ func ReadFromClientConfig(ctx client.Context) (client.Context, error) {

keyring, err := client.NewKeyringFromBackend(ctx, conf.KeyringBackend)
if err != nil {
return ctx, fmt.Errorf("couldn't get key ring: %w", err)
return ctx, fmt.Errorf("couldn't get keyring: %w", err)
}

ctx = ctx.WithKeyring(keyring)
Expand Down
10 changes: 5 additions & 5 deletions client/v2/autocli/flag/address.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,15 +52,15 @@ func (a addressValue) String() string {

// Set implements the flag.Value interface for addressValue it only supports bech32 addresses.
func (a *addressValue) Set(s string) error {
_, err := a.keyring.LookupAddressByKeyName(s)
addr, err := a.keyring.LookupAddressByKeyName(s)
if err == nil {
a.value = s
a.value = addr
return nil
}

_, err = a.addressCodec.StringToBytes(s)
if err != nil {
return fmt.Errorf("invalid bech32 account address: %w", err)
return fmt.Errorf("invalid bech32 account address or key name: %w", err)
}

a.value = s
Expand Down Expand Up @@ -95,9 +95,9 @@ func (a consensusAddressValue) String() string {
}

func (a *consensusAddressValue) Set(s string) error {
_, err := a.keyring.LookupAddressByKeyName(s)
addr, err := a.keyring.LookupAddressByKeyName(s)
if err == nil {
a.value = s
a.value = addr
return nil
}

Expand Down
2 changes: 1 addition & 1 deletion client/v2/autocli/flag/builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ type Builder struct {
ValidatorAddressCodec address.Codec
ConsensusAddressCodec address.Codec

// Keyring
// Keyring implementation
Keyring keyring.Keyring
}

Expand Down
32 changes: 32 additions & 0 deletions crypto/keyring/keyring.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,12 @@ import (
"github.com/cosmos/go-bip39"
"golang.org/x/crypto/bcrypt"

"cosmossdk.io/core/address"
errorsmod "cosmossdk.io/errors"

"github.com/cosmos/cosmos-sdk/client/input"
"github.com/cosmos/cosmos-sdk/codec"
addresscodec "github.com/cosmos/cosmos-sdk/codec/address"
"github.com/cosmos/cosmos-sdk/crypto"
"github.com/cosmos/cosmos-sdk/crypto/hd"
"github.com/cosmos/cosmos-sdk/crypto/ledger"
Expand Down Expand Up @@ -100,6 +102,9 @@ type Keyring interface {
Exporter

Migrator

// Implements client/v2 keyring interface
LookupAddressByKeyName(name string) (string, error)
}

// Signer is implemented by key stores that want to provide signing capabilities.
Expand Down Expand Up @@ -155,6 +160,8 @@ type Options struct {
// indicate whether Ledger should skip DER Conversion on signature,
// depending on which format (DER or BER) the Ledger app returns signatures
LedgerSigSkipDERConv bool
// Address codecs
AddressCodec address.Codec
}

// NewInMemory creates a transient keyring useful for testing
Expand Down Expand Up @@ -240,6 +247,11 @@ func newKeystore(kr keyring.Keyring, cdc codec.Codec, backend string, opts ...Op
ledger.SetSkipDERConversion()
}

if options.AddressCodec == nil {
// fallback to global sdk config
options.AddressCodec = addresscodec.NewBech32Codec(sdk.GetConfig().GetBech32AccountAddrPrefix())
}

return keystore{
db: kr,
cdc: cdc,
Expand Down Expand Up @@ -593,6 +605,26 @@ func (ks keystore) SupportedAlgorithms() (SigningAlgoList, SigningAlgoList) {
return ks.options.SupportedAlgos, ks.options.SupportedAlgosLedger
}

// LookupAddressByKeyName returns the address of a key stored in the keyring
func (ks keystore) LookupAddressByKeyName(name string) (string, error) {
record, err := ks.Key(name)
if err != nil {
return "", err
}

addr, err := record.GetAddress()
if err != nil {
return "", err
}

addrStr, err := ks.options.AddressCodec.BytesToString(addr)
if err != nil {
return "", err
}

return addrStr, nil
}

// SignWithLedger signs a binary message with the ledger device referenced by an Info object
// and returns the signed bytes and the public key. It returns an error if the device could
// not be queried or it returned an error.
Expand Down
7 changes: 6 additions & 1 deletion simapp/simd/cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,12 @@ func NewRootCmd() *cobra.Command {

initRootCmd(rootCmd, encodingConfig.TxConfig, encodingConfig.InterfaceRegistry, encodingConfig.Codec, tempApp.BasicModuleManager)

if err := tempApp.AutoCliOpts().EnhanceRootCommand(rootCmd); err != nil {
// add keyring to autocli opts
autoCliOpts := tempApp.AutoCliOpts()
initClientCtx, _ = config.ReadFromClientConfig(initClientCtx)
autoCliOpts.Keyring = initClientCtx.Keyring
tac0turtle marked this conversation as resolved.
Show resolved Hide resolved

if err := autoCliOpts.EnhanceRootCommand(rootCmd); err != nil {
panic(err)
}

Expand Down
49 changes: 38 additions & 11 deletions simapp/simd/cmd/root_v2.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ import (
"github.com/spf13/cobra"

"cosmossdk.io/client/v2/autocli"
clientv2keyring "cosmossdk.io/client/v2/autocli/keyring"
"cosmossdk.io/core/address"
"cosmossdk.io/depinject"
"cosmossdk.io/log"
"cosmossdk.io/simapp"
Expand All @@ -16,6 +18,7 @@ import (
"github.com/cosmos/cosmos-sdk/client/config"
"github.com/cosmos/cosmos-sdk/codec"
codectypes "github.com/cosmos/cosmos-sdk/codec/types"
"github.com/cosmos/cosmos-sdk/crypto/keyring"
"github.com/cosmos/cosmos-sdk/server"
simtestutil "github.com/cosmos/cosmos-sdk/testutil/sims"
"github.com/cosmos/cosmos-sdk/types/module"
Expand All @@ -31,9 +34,9 @@ func NewRootCmd() *cobra.Command {
interfaceRegistry codectypes.InterfaceRegistry
appCodec codec.Codec
txConfig client.TxConfig
legacyAmino *codec.LegacyAmino
autoCliOpts autocli.AppOptions
moduleBasicManager module.BasicManager
initClientCtx client.Context
)

if err := depinject.Inject(
Expand All @@ -42,26 +45,21 @@ func NewRootCmd() *cobra.Command {
log.NewNopLogger(),
simtestutil.NewAppOptionsWithFlagHome(tempDir()),
),
depinject.Provide(
ProvideClientContext,
ProvideKeyring,
),
),
&interfaceRegistry,
&appCodec,
&txConfig,
&legacyAmino,
&autoCliOpts,
&moduleBasicManager,
&initClientCtx,
); err != nil {
panic(err)
}

initClientCtx := client.Context{}.
WithCodec(appCodec).
WithInterfaceRegistry(interfaceRegistry).
WithLegacyAmino(legacyAmino).
WithInput(os.Stdin).
WithAccountRetriever(types.AccountRetriever{}).
WithHomeDir(simapp.DefaultNodeHome).
WithViper("") // In simapp, we don't use any prefix for env variables.

rootCmd := &cobra.Command{
Use: "simd",
Short: "simulation app",
Expand Down Expand Up @@ -116,3 +114,32 @@ func NewRootCmd() *cobra.Command {

return rootCmd
}

func ProvideClientContext(appCodec codec.Codec, interfaceRegistry codectypes.InterfaceRegistry, legacyAmino *codec.LegacyAmino) client.Context {
initClientCtx := client.Context{}.
WithCodec(appCodec).
WithInterfaceRegistry(interfaceRegistry).
WithLegacyAmino(legacyAmino).
WithInput(os.Stdin).
WithAccountRetriever(types.AccountRetriever{}).
WithHomeDir(simapp.DefaultNodeHome).
WithViper("") // In simapp, we don't use any prefix for env variables.

// Read the config again to overwrite the default values with the values from the config file
initClientCtx, _ = config.ReadFromClientConfig(initClientCtx)

return initClientCtx
}

func ProvideKeyring(clientCtx client.Context, addressCodec address.Codec) (clientv2keyring.Keyring, error) {
clientCtx = clientCtx.WithKeyringOptions(append(clientCtx.KeyringOptions, func(options *keyring.Options) {
options.AddressCodec = addressCodec
})...)

kb, err := client.NewKeyringFromBackend(clientCtx, clientCtx.Keyring.Backend())
if err != nil {
return nil, err
}

return kb, nil
}
julienrbrt marked this conversation as resolved.
Show resolved Hide resolved