Skip to content

Commit

Permalink
refactor: decouple from sdk/codec in amino codec usage (#20369)
Browse files Browse the repository at this point in the history
  • Loading branch information
kocubinski committed May 14, 2024
1 parent fbc61d2 commit 493d486
Show file tree
Hide file tree
Showing 63 changed files with 286 additions and 195 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,7 @@ Every module contains its own CHANGELOG.md. Please refer to the module you are i

### API Breaking Changes

* (types)[#20369](https://github.com/cosmos/cosmos-sdk/pull/20369) The signature of `HasAminoCodec` has changed to accept a `core/legacy.Amino` interface instead of `codec.LegacyAmino`.
* (x/simulation)[#20056](https://github.com/cosmos/cosmos-sdk/pull/20056) `SimulateFromSeed` now takes an address codec as argument.
* (x/crisis) [#20043](https://github.com/cosmos/cosmos-sdk/pull/20043) Changed `NewMsgVerifyInvariant` to accept a string as argument instead of an `AccAddress`.
* (x/genutil) [#19926](https://github.com/cosmos/cosmos-sdk/pull/19926) Removal of the Address.String() method and related changes:
Expand Down
7 changes: 7 additions & 0 deletions UPGRADING.md
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,13 @@ The signature of the extension interface `HasRegisterInterfaces` has been change
+func (AppModule) RegisterInterfaces(registry registry.InterfaceRegistrar) {
```

The signature of the extension interface `HasAminoCodec` has been changed to accept a `cosmossdk.io/core/legacy.Amino` instead of a `codec.LegacyAmino`. Modules should update their `HasAminoCodec` implementation to accept a `cosmossdk.io/core/legacy.Amino` interface.

```diff
-func (AppModule) RegisterLegacyAminoCodec(cdc *codec.LegacyAmino) {
+func (AppModule) RegisterLegacyAminoCodec(cdc legacy.Amino) {
```

##### Simulation

`MsgSimulatorFn` has been updated to return an error. Its context argument has been removed, and an address.Codec has
Expand Down
25 changes: 18 additions & 7 deletions codec/amino.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ import (
cmttypes "github.com/cometbft/cometbft/types"
"github.com/tendermint/go-amino"

"cosmossdk.io/core/legacy"

"github.com/cosmos/cosmos-sdk/codec/types"
)

Expand All @@ -23,15 +25,17 @@ func (cdc *LegacyAmino) Seal() {
cdc.Amino.Seal()
}

var _ legacy.Amino = &LegacyAmino{}

func NewLegacyAmino() *LegacyAmino {
return &LegacyAmino{amino.NewCodec()}
}

// RegisterEvidences registers CometBFT evidence types with the provided Amino
// codec.
func RegisterEvidences(cdc *LegacyAmino) {
cdc.Amino.RegisterInterface((*cmttypes.Evidence)(nil), nil)
cdc.Amino.RegisterConcrete(&cmttypes.DuplicateVoteEvidence{}, "tendermint/DuplicateVoteEvidence", nil)
func RegisterEvidences(cdc legacy.Amino) {
cdc.RegisterInterface((*cmttypes.Evidence)(nil), nil)
cdc.RegisterConcrete(&cmttypes.DuplicateVoteEvidence{}, "tendermint/DuplicateVoteEvidence")
}

// MarshalJSONIndent provides a utility for indented JSON encoding of an object
Expand Down Expand Up @@ -175,12 +179,19 @@ func (*LegacyAmino) UnpackAny(*types.Any, interface{}) error {
return errors.New("AminoCodec can't handle unpack protobuf Any's")
}

func (cdc *LegacyAmino) RegisterInterface(ptr interface{}, iopts *amino.InterfaceOptions) {
cdc.Amino.RegisterInterface(ptr, iopts)
func (cdc *LegacyAmino) RegisterInterface(ptr interface{}, iopts *legacy.InterfaceOptions) {
if iopts == nil {
cdc.Amino.RegisterInterface(ptr, nil)
} else {
cdc.Amino.RegisterInterface(ptr, &amino.InterfaceOptions{
Priority: iopts.Priority,
AlwaysDisambiguate: iopts.AlwaysDisambiguate,
})
}
}

func (cdc *LegacyAmino) RegisterConcrete(o interface{}, name string, copts *amino.ConcreteOptions) {
cdc.Amino.RegisterConcrete(o, name, copts)
func (cdc *LegacyAmino) RegisterConcrete(o interface{}, name string) {
cdc.Amino.RegisterConcrete(o, name, nil)
}

func (cdc *LegacyAmino) MarshalJSONIndent(o interface{}, prefix, indent string) ([]byte, error) {
Expand Down
4 changes: 2 additions & 2 deletions codec/amino_codec_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ func createTestCodec() *codec.LegacyAmino {
cdc.RegisterInterface((*testdata.Animal)(nil), nil)
// NOTE: since we unmarshal interface using pointers, we need to register a pointer
// types here.
cdc.RegisterConcrete(&testdata.Dog{}, "testdata/Dog", nil)
cdc.RegisterConcrete(&testdata.Cat{}, "testdata/Cat", nil)
cdc.RegisterConcrete(&testdata.Dog{}, "testdata/Dog")
cdc.RegisterConcrete(&testdata.Cat{}, "testdata/Cat")

return cdc
}
Expand Down
47 changes: 47 additions & 0 deletions codec/depinject.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package codec

import (
"github.com/cosmos/gogoproto/proto"

"cosmossdk.io/core/address"
"cosmossdk.io/core/legacy"
"cosmossdk.io/x/tx/signing"

"github.com/cosmos/cosmos-sdk/codec/types"
)

func ProvideInterfaceRegistry(
addressCodec address.Codec,
validatorAddressCodec address.ValidatorAddressCodec,
customGetSigners []signing.CustomGetSigner,
) (types.InterfaceRegistry, error) {
signingOptions := signing.Options{
AddressCodec: addressCodec,
ValidatorAddressCodec: validatorAddressCodec,
}
for _, signer := range customGetSigners {
signingOptions.DefineCustomGetSigners(signer.MsgType, signer.Fn)
}

interfaceRegistry, err := types.NewInterfaceRegistryWithOptions(types.InterfaceRegistryOptions{
ProtoFiles: proto.HybridResolver,
SigningOptions: signingOptions,
})
if err != nil {
return nil, err
}

if err := interfaceRegistry.SigningContext().Validate(); err != nil {
return nil, err
}

return interfaceRegistry, nil
}

func ProvideLegacyAmino() legacy.Amino {
return NewLegacyAmino()
}

func ProvideProtoCodec(interfaceRegistry types.InterfaceRegistry) *ProtoCodec {
return NewProtoCodec(interfaceRegistry)
}
7 changes: 4 additions & 3 deletions codec/legacy/amino_msg.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,17 @@ package legacy
import (
"fmt"

"github.com/cosmos/cosmos-sdk/codec"
"cosmossdk.io/core/legacy"

sdk "github.com/cosmos/cosmos-sdk/types"
)

// RegisterAminoMsg first checks that the msgName is <40 chars
// (else this would break ledger nano signing: https://github.com/cosmos/cosmos-sdk/issues/10870),
// then registers the concrete msg type with amino.
func RegisterAminoMsg(cdc *codec.LegacyAmino, msg sdk.Msg, msgName string) {
func RegisterAminoMsg(cdc legacy.Amino, msg sdk.Msg, msgName string) {
if len(msgName) > 39 {
panic(fmt.Errorf("msg name %s is too long to be registered with amino", msgName))
}
cdc.RegisterConcrete(msg, msgName, nil)
cdc.RegisterConcrete(msg, msgName)
}
14 changes: 14 additions & 0 deletions core/legacy/amino.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package legacy

type Amino interface {
// RegisterInterface registers an interface and its concrete type with the Amino codec.
RegisterInterface(interfacePtr any, iopts *InterfaceOptions)

// RegisterConcrete registers a concrete type with the Amino codec.
RegisterConcrete(cdcType interface{}, name string)
}

type InterfaceOptions struct {
Priority []string // Disamb priority.
AlwaysDisambiguate bool // If true, include disamb for all types.
}
19 changes: 10 additions & 9 deletions crypto/codec/amino.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ package codec
import (
"github.com/cometbft/cometbft/crypto/sr25519"

"github.com/cosmos/cosmos-sdk/codec"
"cosmossdk.io/core/legacy"

"github.com/cosmos/cosmos-sdk/crypto/keys/ed25519"
kmultisig "github.com/cosmos/cosmos-sdk/crypto/keys/multisig"
"github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1"
Expand All @@ -12,22 +13,22 @@ import (

// RegisterCrypto registers all crypto dependency types with the provided Amino
// codec.
func RegisterCrypto(cdc *codec.LegacyAmino) {
func RegisterCrypto(cdc legacy.Amino) {
cdc.RegisterInterface((*cryptotypes.PubKey)(nil), nil)
cdc.RegisterConcrete(sr25519.PubKey{},
sr25519.PubKeyName, nil)
sr25519.PubKeyName)
cdc.RegisterConcrete(&ed25519.PubKey{},
ed25519.PubKeyName, nil)
ed25519.PubKeyName)
cdc.RegisterConcrete(&secp256k1.PubKey{},
secp256k1.PubKeyName, nil)
secp256k1.PubKeyName)
cdc.RegisterConcrete(&kmultisig.LegacyAminoPubKey{},
kmultisig.PubKeyAminoRoute, nil)
kmultisig.PubKeyAminoRoute)

cdc.RegisterInterface((*cryptotypes.PrivKey)(nil), nil)
cdc.RegisterConcrete(sr25519.PrivKey{},
sr25519.PrivKeyName, nil)
sr25519.PrivKeyName)
cdc.RegisterConcrete(&ed25519.PrivKey{},
ed25519.PrivKeyName, nil)
ed25519.PrivKeyName)
cdc.RegisterConcrete(&secp256k1.PrivKey{},
secp256k1.PrivKeyName, nil)
secp256k1.PrivKeyName)
}
10 changes: 5 additions & 5 deletions crypto/keyring/codec.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,9 @@ func init() {
// RegisterLegacyAminoCodec registers concrete types and interfaces on the given codec.
func RegisterLegacyAminoCodec(cdc *codec.LegacyAmino) {
cdc.RegisterInterface((*LegacyInfo)(nil), nil)
cdc.RegisterConcrete(hd.BIP44Params{}, "crypto/keys/hd/BIP44Params", nil)
cdc.RegisterConcrete(legacyLocalInfo{}, "crypto/keys/localInfo", nil)
cdc.RegisterConcrete(legacyLedgerInfo{}, "crypto/keys/ledgerInfo", nil)
cdc.RegisterConcrete(legacyOfflineInfo{}, "crypto/keys/offlineInfo", nil)
cdc.RegisterConcrete(LegacyMultiInfo{}, "crypto/keys/multiInfo", nil)
cdc.RegisterConcrete(hd.BIP44Params{}, "crypto/keys/hd/BIP44Params")
cdc.RegisterConcrete(legacyLocalInfo{}, "crypto/keys/localInfo")
cdc.RegisterConcrete(legacyLedgerInfo{}, "crypto/keys/ledgerInfo")
cdc.RegisterConcrete(legacyOfflineInfo{}, "crypto/keys/offlineInfo")
cdc.RegisterConcrete(LegacyMultiInfo{}, "crypto/keys/multiInfo")
}
8 changes: 4 additions & 4 deletions crypto/keys/multisig/codec.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,11 @@ var AminoCdc = codec.NewLegacyAmino()
func init() {
AminoCdc.RegisterInterface((*cryptotypes.PubKey)(nil), nil)
AminoCdc.RegisterConcrete(ed25519.PubKey{},
ed25519.PubKeyName, nil)
ed25519.PubKeyName)
AminoCdc.RegisterConcrete(sr25519.PubKey{},
sr25519.PubKeyName, nil)
sr25519.PubKeyName)
AminoCdc.RegisterConcrete(&secp256k1.PubKey{},
secp256k1.PubKeyName, nil)
secp256k1.PubKeyName)
AminoCdc.RegisterConcrete(&LegacyAminoPubKey{},
PubKeyAminoRoute, nil)
PubKeyAminoRoute)
}
2 changes: 1 addition & 1 deletion crypto/ledger/amino.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,5 @@ func init() {
// RegisterAmino registers all go-crypto related types in the given (amino) codec.
func RegisterAmino(cdc *codec.LegacyAmino) {
cdc.RegisterConcrete(PrivKeyLedgerSecp256k1{},
"tendermint/PrivKeyLedgerSecp256k1", nil)
"tendermint/PrivKeyLedgerSecp256k1")
}
3 changes: 2 additions & 1 deletion runtime/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
runtimev1alpha1 "cosmossdk.io/api/cosmos/app/runtime/v1alpha1"
appv1alpha1 "cosmossdk.io/api/cosmos/app/v1alpha1"
"cosmossdk.io/core/appmodule"
"cosmossdk.io/core/legacy"
"cosmossdk.io/log"
storetypes "cosmossdk.io/store/types"
authtx "cosmossdk.io/x/auth/tx"
Expand Down Expand Up @@ -46,7 +47,7 @@ type App struct {
storeKeys []storetypes.StoreKey
interfaceRegistry codectypes.InterfaceRegistry
cdc codec.Codec
amino *codec.LegacyAmino
amino legacy.Amino
baseAppOptions []BaseAppOption
msgServiceRouter *baseapp.MsgServiceRouter
grpcQueryRouter *baseapp.GRPCQueryRouter
Expand Down
53 changes: 14 additions & 39 deletions runtime/module.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,12 @@ import (
"cosmossdk.io/core/appmodule"
"cosmossdk.io/core/comet"
"cosmossdk.io/core/genesis"
"cosmossdk.io/core/legacy"
"cosmossdk.io/core/store"
"cosmossdk.io/depinject"
"cosmossdk.io/depinject/appconfig"
"cosmossdk.io/log"
storetypes "cosmossdk.io/store/types"
"cosmossdk.io/x/tx/signing"

"github.com/cosmos/cosmos-sdk/baseapp"
"github.com/cosmos/cosmos-sdk/codec"
Expand Down Expand Up @@ -93,7 +93,11 @@ func init() {
appconfig.RegisterModule(&runtimev1alpha1.Module{},
appconfig.Provide(
ProvideApp,
ProvideInterfaceRegistry,
// to decouple runtime from sdk/codec ProvideInterfaceReistry can be registered from the app
// i.e. in the call to depinject.Inject(...)
codec.ProvideInterfaceRegistry,
codec.ProvideLegacyAmino,
codec.ProvideProtoCodec,
ProvideKVStoreKey,
ProvideTransientStoreKey,
ProvideMemoryStoreKey,
Expand All @@ -109,9 +113,11 @@ func init() {
)
}

func ProvideApp(interfaceRegistry codectypes.InterfaceRegistry) (
codec.Codec,
*codec.LegacyAmino,
func ProvideApp(
interfaceRegistry codectypes.InterfaceRegistry,
amino legacy.Amino,
protoCodec *codec.ProtoCodec,
) (
*AppBuilder,
*baseapp.MsgServiceRouter,
*baseapp.GRPCQueryRouter,
Expand All @@ -130,25 +136,22 @@ func ProvideApp(interfaceRegistry codectypes.InterfaceRegistry) (
_, _ = fmt.Fprintln(os.Stderr, err.Error())
}

amino := codec.NewLegacyAmino()

std.RegisterInterfaces(interfaceRegistry)
std.RegisterLegacyAminoCodec(amino)

cdc := codec.NewProtoCodec(interfaceRegistry)
msgServiceRouter := baseapp.NewMsgServiceRouter()
grpcQueryRouter := baseapp.NewGRPCQueryRouter()
app := &App{
storeKeys: nil,
interfaceRegistry: interfaceRegistry,
cdc: cdc,
cdc: protoCodec,
amino: amino,
msgServiceRouter: msgServiceRouter,
grpcQueryRouter: grpcQueryRouter,
}
appBuilder := &AppBuilder{app}

return cdc, amino, appBuilder, msgServiceRouter, grpcQueryRouter, appModule{app}, protoFiles, protoTypes, nil
return appBuilder, msgServiceRouter, grpcQueryRouter, appModule{app}, protoFiles, protoTypes, nil
}

type AppInputs struct {
Expand All @@ -161,7 +164,7 @@ type AppInputs struct {
ModuleManager *module.Manager
BaseAppOptions []BaseAppOption
InterfaceRegistry codectypes.InterfaceRegistry
LegacyAmino *codec.LegacyAmino
LegacyAmino legacy.Amino
}

func SetupAppBuilder(inputs AppInputs) {
Expand All @@ -175,34 +178,6 @@ func SetupAppBuilder(inputs AppInputs) {
app.ModuleManager.RegisterLegacyAminoCodec(inputs.LegacyAmino)
}

func ProvideInterfaceRegistry(
addressCodec address.Codec,
validatorAddressCodec address.ValidatorAddressCodec,
customGetSigners []signing.CustomGetSigner,
) (codectypes.InterfaceRegistry, error) {
signingOptions := signing.Options{
AddressCodec: addressCodec,
ValidatorAddressCodec: validatorAddressCodec,
}
for _, signer := range customGetSigners {
signingOptions.DefineCustomGetSigners(signer.MsgType, signer.Fn)
}

interfaceRegistry, err := codectypes.NewInterfaceRegistryWithOptions(codectypes.InterfaceRegistryOptions{
ProtoFiles: proto.HybridResolver,
SigningOptions: signingOptions,
})
if err != nil {
return nil, err
}

if err := interfaceRegistry.SigningContext().Validate(); err != nil {
return nil, err
}

return interfaceRegistry, nil
}

func registerStoreKey(wrapper *AppBuilder, key storetypes.StoreKey) {
wrapper.app.storeKeys = append(wrapper.app.storeKeys, key)
}
Expand Down

0 comments on commit 493d486

Please sign in to comment.