Is there an existing issue for this?
What happened?
The top of NewSimApp looks like this (in v0.50.10):
|
interfaceRegistry, _ := types.NewInterfaceRegistryWithOptions(types.InterfaceRegistryOptions{ |
|
ProtoFiles: proto.HybridResolver, |
|
SigningOptions: signing.Options{ |
|
AddressCodec: address.Bech32Codec{ |
|
Bech32Prefix: sdk.GetConfig().GetBech32AccountAddrPrefix(), |
|
}, |
|
ValidatorAddressCodec: address.Bech32Codec{ |
|
Bech32Prefix: sdk.GetConfig().GetBech32ValidatorAddrPrefix(), |
|
}, |
|
}, |
|
}) |
|
appCodec := codec.NewProtoCodec(interfaceRegistry) |
|
legacyAmino := codec.NewLegacyAmino() |
|
txConfig := tx.NewTxConfig(appCodec, tx.DefaultSignModes) |
|
|
|
if err := txConfig.SigningContext().Validate(); err != nil { |
|
panic(err) |
|
} |
If CustomGetSigners are added to the SigningOptions (that are provided to NewInterfaceRegistryWithOptions), they don't end up being conveyed to the result of NewTxConfig. That causes txConfig.SigningContext().Validate() to return an error for the protos that use a custom GetSigners method (and don't have a signer option): no cosmos.msg.v1.signer option found for message <msg name>; use DefineCustomGetSigners to specify a custom getter.
I would not expect to get an error there, though, since the interfaceRegistry and appCodec both handle the custom-get-signer stuff just fine. I.e. Neither interfaceRegistry.SigningContext().Validate() nor appCodec.InterfaceRegistry().SigningContext().Validate() returns an error.
A workaround is to use NewTxConfigWithOptions instead of NewTxConfig, and extract those signing options into its own variable so that they can be provided when creating both the interface registry and the tx-config. But I feel that NewTxConfig should get that info from the interface registry in the provided appCodec, and NewTxConfigWithOptions should too when the authtx.ConfigOptions.SigningOptions is nil (or maybe there's a more specific field to look at).
Cosmos SDK Version
v0.50.10
How to reproduce?
You'll need a proto with an endpoint that has a request message without a cosmos.msg.v1.signer option and a custom GetSigners function for it.
Add that info to the SigningOptions.CustomGetSigners map (e.g. using DefineCustomGetSigners) in the InterfaceRegistryOptions.SigningOptions that is provided to NewInterfaceRegistryWithOptions
Example code that panics:
sigOpts := signing.Options{
AddressCodec: address.Bech32Codec{Bech32Prefix: sdk.GetConfig().GetBech32AccountAddrPrefix()},
ValidatorAddressCodec: address.Bech32Codec{Bech32Prefix: sdk.GetConfig().GetBech32ValidatorAddrPrefix()},
}
sigOpts.DefineCustomGetSigners("", nil) // TODO: Fill in appropriately
interfaceRegistry, _ := types.NewInterfaceRegistryWithOptions(types.InterfaceRegistryOptions{
ProtoFiles: proto.HybridResolver,
SigningOptions: sigOpts,
})
appCodec := codec.NewProtoCodec(interfaceRegistry)
legacyAmino := codec.NewLegacyAmino()
txConfig := tx.NewTxConfig(appCodec, tx.DefaultSignModes)
if err := txConfig.SigningContext().Validate(); err != nil {
panic(err)
}
When that runs, you'll get a panic because txConfig.SigningContext().Validate() will return an error: no cosmos.msg.v1.signer option found for message <msg name>; use DefineCustomGetSigners to specify a custom getter.
The workaround looks something like this:
sigOpts := signing.Options{
AddressCodec: address.Bech32Codec{Bech32Prefix: sdk.GetConfig().GetBech32AccountAddrPrefix()},
ValidatorAddressCodec: address.Bech32Codec{Bech32Prefix: sdk.GetConfig().GetBech32ValidatorAddrPrefix()},
}
sigOpts.DefineCustomGetSigners("", nil) // TODO: Fill in appropriately
interfaceRegistry, _ := types.NewInterfaceRegistryWithOptions(types.InterfaceRegistryOptions{
ProtoFiles: proto.HybridResolver,
SigningOptions: sigOpts,
})
appCodec := codec.NewProtoCodec(interfaceRegistry)
legacyAmino := codec.NewLegacyAmino()
txConfigOpts := authtx.ConfigOptions{
EnabledSignModes: authtx.DefaultSignModes,
SigningOptions: &signingOptions,
}
txConfig, err := authtx.NewTxConfigWithOptions(appCodec, txConfigOpts)
if err != nil {
panic(err)
}
if err := txConfig.SigningContext().Validate(); err != nil {
panic(err)
}
Then, later, after the bank keeper is made, to enable sign mode textual, you could just update txConfigOpts and give it to NewTxConfigWithOptions again.
txConfigOpts.EnabledSignModes = append(txConfigOpts.EnabledSignModes, sigtypes.SignMode_SIGN_MODE_TEXTUAL)
txConfigOpts.TextualCoinMetadataQueryFn = txmodule.NewBankKeeperCoinMetadataQueryFn(app.BankKeeper)
txConfig, err = authtx.NewTxConfigWithOptions(appCodec, txConfigOpts)
if err != nil {
panic(err)
}
But again, I feel like the custom GetSigners stuff should automatically get propagated from the interface registry in the appCodec to the txConfig without needing to also provide the signing options to NewTxConfigWithOptions.
Is there an existing issue for this?
What happened?
The top of
NewSimApplooks like this (inv0.50.10):cosmos-sdk/simapp/app.go
Lines 197 to 214 in 6dc6e8b
If
CustomGetSignersare added to theSigningOptions(that are provided toNewInterfaceRegistryWithOptions), they don't end up being conveyed to the result ofNewTxConfig. That causestxConfig.SigningContext().Validate()to return an error for the protos that use a customGetSignersmethod (and don't have a signer option):no cosmos.msg.v1.signer option found for message <msg name>; use DefineCustomGetSigners to specify a custom getter.I would not expect to get an error there, though, since the
interfaceRegistryandappCodecboth handle the custom-get-signer stuff just fine. I.e. NeitherinterfaceRegistry.SigningContext().Validate()norappCodec.InterfaceRegistry().SigningContext().Validate()returns an error.A workaround is to use
NewTxConfigWithOptionsinstead ofNewTxConfig, and extract those signing options into its own variable so that they can be provided when creating both the interface registry and the tx-config. But I feel thatNewTxConfigshould get that info from the interface registry in the providedappCodec, andNewTxConfigWithOptionsshould too when theauthtx.ConfigOptions.SigningOptionsisnil(or maybe there's a more specific field to look at).Cosmos SDK Version
v0.50.10
How to reproduce?
You'll need a proto with an endpoint that has a request message without a
cosmos.msg.v1.signeroption and a customGetSignersfunction for it.Add that info to the
SigningOptions.CustomGetSignersmap (e.g. usingDefineCustomGetSigners) in theInterfaceRegistryOptions.SigningOptionsthat is provided toNewInterfaceRegistryWithOptionsExample code that panics:
When that runs, you'll get a panic because
txConfig.SigningContext().Validate()will return an error:no cosmos.msg.v1.signer option found for message <msg name>; use DefineCustomGetSigners to specify a custom getter.The workaround looks something like this:
Then, later, after the bank keeper is made, to enable sign mode textual, you could just update
txConfigOptsand give it toNewTxConfigWithOptionsagain.But again, I feel like the custom
GetSignersstuff should automatically get propagated from the interface registry in theappCodecto thetxConfigwithout needing to also provide the signing options toNewTxConfigWithOptions.