Skip to content

Commit

Permalink
feat: custom get signers (#16340)
Browse files Browse the repository at this point in the history
Co-authored-by: Aaron Craelius <[email protected]>
  • Loading branch information
kocubinski and aaronc authored Jun 6, 2023
1 parent daaffb8 commit bf6edae
Show file tree
Hide file tree
Showing 26 changed files with 481 additions and 959 deletions.
9 changes: 6 additions & 3 deletions codec/proto_codec_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (

bankv1beta1 "cosmossdk.io/api/cosmos/bank/v1beta1"
basev1beta1 "cosmossdk.io/api/cosmos/base/v1beta1"
"cosmossdk.io/x/tx/signing"
"github.com/cosmos/gogoproto/proto"
"github.com/stretchr/testify/require"
"google.golang.org/grpc/codes"
Expand Down Expand Up @@ -176,9 +177,11 @@ func BenchmarkProtoCodecMarshalLengthPrefixed(b *testing.B) {

func TestGetSigners(t *testing.T) {
interfaceRegistry, err := types.NewInterfaceRegistryWithOptions(types.InterfaceRegistryOptions{
AddressCodec: testAddressCodec{},
ValidatorAddressCodec: testAddressCodec{},
ProtoFiles: protoregistry.GlobalFiles,
SigningOptions: signing.Options{
AddressCodec: testAddressCodec{},
ValidatorAddressCodec: testAddressCodec{},
},
ProtoFiles: protoregistry.GlobalFiles,
})
require.NoError(t, err)
cdc := codec.NewProtoCodec(interfaceRegistry)
Expand Down
9 changes: 6 additions & 3 deletions codec/testutil/codec.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package testutil

import (
"cosmossdk.io/x/tx/signing"
"github.com/cosmos/gogoproto/proto"

"github.com/cosmos/cosmos-sdk/codec"
Expand All @@ -27,9 +28,11 @@ func (o CodecOptions) NewInterfaceRegistry() codectypes.InterfaceRegistry {
}

ir, err := codectypes.NewInterfaceRegistryWithOptions(codectypes.InterfaceRegistryOptions{
ProtoFiles: proto.HybridResolver,
AddressCodec: address.NewBech32Codec(accAddressPrefix),
ValidatorAddressCodec: address.NewBech32Codec(valAddressPrefix),
ProtoFiles: proto.HybridResolver,
SigningOptions: signing.Options{
AddressCodec: address.NewBech32Codec(accAddressPrefix),
ValidatorAddressCodec: address.NewBech32Codec(valAddressPrefix),
},
})
if err != nil {
panic(err)
Expand Down
25 changes: 9 additions & 16 deletions codec/types/interface_registry.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,6 @@ import (
"google.golang.org/protobuf/reflect/protodesc"
"google.golang.org/protobuf/reflect/protoreflect"

"cosmossdk.io/core/address"

"cosmossdk.io/x/tx/signing"
)

Expand Down Expand Up @@ -114,9 +112,11 @@ type interfaceMap = map[string]reflect.Type
// NewInterfaceRegistry returns a new InterfaceRegistry
func NewInterfaceRegistry() InterfaceRegistry {
registry, err := NewInterfaceRegistryWithOptions(InterfaceRegistryOptions{
ProtoFiles: proto.HybridResolver,
AddressCodec: failingAddressCodec{},
ValidatorAddressCodec: failingAddressCodec{},
ProtoFiles: proto.HybridResolver,
SigningOptions: signing.Options{
AddressCodec: failingAddressCodec{},
ValidatorAddressCodec: failingAddressCodec{},
},
})
if err != nil {
panic(err)
Expand All @@ -129,11 +129,8 @@ type InterfaceRegistryOptions struct {
// ProtoFiles is the set of files to use for the registry. It is required.
ProtoFiles signing.ProtoFileResolver

// AddressCodec is the address codec to use for the registry. It is required.
AddressCodec address.Codec

// ValidatorAddressCodec is the validator address codec to use for the registry. It is required.
ValidatorAddressCodec address.Codec
// SigningOptions are the signing options to use for the registry.
SigningOptions signing.Options
}

// NewInterfaceRegistryWithOptions returns a new InterfaceRegistry with the given options.
Expand All @@ -142,12 +139,8 @@ func NewInterfaceRegistryWithOptions(options InterfaceRegistryOptions) (Interfac
return nil, fmt.Errorf("proto files must be provided")
}

signingCtx, err := signing.NewContext(signing.Options{
FileResolver: options.ProtoFiles,
TypeResolver: nil,
AddressCodec: options.AddressCodec,
ValidatorAddressCodec: options.ValidatorAddressCodec,
})
options.SigningOptions.FileResolver = options.ProtoFiles
signingCtx, err := signing.NewContext(options.SigningOptions)
if err != nil {
return nil, err
}
Expand Down
58 changes: 34 additions & 24 deletions runtime/module.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
appv1alpha1 "cosmossdk.io/api/cosmos/app/v1alpha1"
"cosmossdk.io/depinject"
"cosmossdk.io/log"
"cosmossdk.io/x/tx/signing"
"github.com/cosmos/gogoproto/proto"
"google.golang.org/protobuf/reflect/protodesc"
"google.golang.org/protobuf/reflect/protoregistry"
Expand All @@ -19,6 +20,7 @@ import (
"cosmossdk.io/core/header"
"cosmossdk.io/core/store"
storetypes "cosmossdk.io/store/types"

"github.com/cosmos/cosmos-sdk/codec/address"

"github.com/cosmos/cosmos-sdk/baseapp"
Expand Down Expand Up @@ -60,6 +62,7 @@ func init() {
appmodule.Register(&runtimev1alpha1.Module{},
appmodule.Provide(
ProvideApp,
ProvideInterfaceRegistry,
ProvideKVStoreKey,
ProvideTransientStoreKey,
ProvideMemoryStoreKey,
Expand All @@ -76,8 +79,7 @@ func init() {
)
}

func ProvideApp() (
codectypes.InterfaceRegistry,
func ProvideApp(interfaceRegistry codectypes.InterfaceRegistry) (
codec.Codec,
*codec.LegacyAmino,
*AppBuilder,
Expand All @@ -98,27 +100,6 @@ func ProvideApp() (
_, _ = fmt.Fprintln(os.Stderr, err.Error())
}

interfaceRegistry, err := codectypes.NewInterfaceRegistryWithOptions(codectypes.InterfaceRegistryOptions{
ProtoFiles: proto.HybridResolver,
// using the global prefixes is a temporary solution until we refactor this
// to get the address.Codec's from the container
AddressCodec: address.Bech32Codec{
Bech32Prefix: sdk.GetConfig().GetBech32AccountAddrPrefix(),
},
ValidatorAddressCodec: address.Bech32Codec{
Bech32Prefix: sdk.GetConfig().GetBech32ValidatorAddrPrefix(),
},
})
if err != nil {
return nil, nil, nil, nil, nil, nil, nil, nil, nil, err
}

// validate the signing context to make sure that messages are properly configured
// with cosmos.msg.v1.signer
if err := interfaceRegistry.SigningContext().Validate(); err != nil {
return nil, nil, nil, nil, nil, nil, nil, nil, nil, err
}

amino := codec.NewLegacyAmino()

std.RegisterInterfaces(interfaceRegistry)
Expand All @@ -136,7 +117,7 @@ func ProvideApp() (
}
appBuilder := &AppBuilder{app}

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

type AppInputs struct {
Expand Down Expand Up @@ -176,6 +157,35 @@ func SetupAppBuilder(inputs AppInputs) {
}
}

func ProvideInterfaceRegistry(customGetSigners []signing.CustomGetSigner) (codectypes.InterfaceRegistry, error) {
signingOptions := signing.Options{
// using the global prefixes is a temporary solution until we refactor this
// to get the address.Codec's from the container
AddressCodec: address.Bech32Codec{
Bech32Prefix: sdk.GetConfig().GetBech32AccountAddrPrefix(),
},
ValidatorAddressCodec: address.Bech32Codec{
Bech32Prefix: sdk.GetConfig().GetBech32ValidatorAddrPrefix(),
},
}
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
}
err = interfaceRegistry.SigningContext().Validate()
if 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
14 changes: 9 additions & 5 deletions simapp/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,13 @@ import (
"path/filepath"

"cosmossdk.io/log"
"cosmossdk.io/x/tx/signing"

autocliv1 "cosmossdk.io/api/cosmos/autocli/v1"
reflectionv1 "cosmossdk.io/api/cosmos/reflection/v1"
"cosmossdk.io/client/v2/autocli"
"cosmossdk.io/core/appmodule"

"github.com/cosmos/cosmos-sdk/codec/address"

authcodec "github.com/cosmos/cosmos-sdk/x/auth/codec"
Expand Down Expand Up @@ -229,11 +231,13 @@ func NewSimApp(
) *SimApp {
interfaceRegistry, _ := types.NewInterfaceRegistryWithOptions(types.InterfaceRegistryOptions{
ProtoFiles: proto.HybridResolver,
AddressCodec: address.Bech32Codec{
Bech32Prefix: sdk.GetConfig().GetBech32AccountAddrPrefix(),
},
ValidatorAddressCodec: address.Bech32Codec{
Bech32Prefix: sdk.GetConfig().GetBech32ValidatorAddrPrefix(),
SigningOptions: signing.Options{
AddressCodec: address.Bech32Codec{
Bech32Prefix: sdk.GetConfig().GetBech32AccountAddrPrefix(),
},
ValidatorAddressCodec: address.Bech32Codec{
Bech32Prefix: sdk.GetConfig().GetBech32ValidatorAddrPrefix(),
},
},
})
appCodec := codec.NewProtoCodec(interfaceRegistry)
Expand Down
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,9 @@ import (
ed25519types "github.com/cosmos/cosmos-sdk/crypto/keys/ed25519"
"github.com/cosmos/cosmos-sdk/crypto/keys/multisig"
secp256k1types "github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1"
gogo_testpb "github.com/cosmos/cosmos-sdk/tests/integration/aminojson/internal/gogo/testpb"
pulsar_testpb "github.com/cosmos/cosmos-sdk/tests/integration/aminojson/internal/pulsar/testpb"
"github.com/cosmos/cosmos-sdk/tests/integration/rapidgen"
gogo_testpb "github.com/cosmos/cosmos-sdk/tests/integration/tx/internal/gogo/testpb"
pulsar_testpb "github.com/cosmos/cosmos-sdk/tests/integration/tx/internal/pulsar/testpb"
"github.com/cosmos/cosmos-sdk/testutil/testdata"
"github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/types/bech32"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,10 @@ import (
"github.com/stretchr/testify/require"

"cosmossdk.io/x/tx/signing/aminojson"

"github.com/cosmos/cosmos-sdk/codec"
gogopb "github.com/cosmos/cosmos-sdk/tests/integration/aminojson/internal/gogo/testpb"
pulsarpb "github.com/cosmos/cosmos-sdk/tests/integration/aminojson/internal/pulsar/testpb"
gogopb "github.com/cosmos/cosmos-sdk/tests/integration/tx/internal/gogo/testpb"
pulsarpb "github.com/cosmos/cosmos-sdk/tests/integration/tx/internal/pulsar/testpb"
)

func TestRepeatedFields(t *testing.T) {
Expand Down
74 changes: 74 additions & 0 deletions tests/integration/tx/context_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
package tx

import (
"testing"

"cosmossdk.io/depinject"
"cosmossdk.io/log"
"cosmossdk.io/x/tx/signing"
"github.com/stretchr/testify/require"
"google.golang.org/protobuf/proto"

codectypes "github.com/cosmos/cosmos-sdk/codec/types"
"github.com/cosmos/cosmos-sdk/tests/integration/tx/internal/pulsar/testpb"
"github.com/cosmos/cosmos-sdk/testutil/configurator"
simtestutil "github.com/cosmos/cosmos-sdk/testutil/sims"
)

func ProvideCustomGetSigners() signing.CustomGetSigner {
return signing.CustomGetSigner{
MsgType: proto.MessageName(&testpb.TestRepeatedFields{}),
Fn: func(msg proto.Message) ([][]byte, error) {
testMsg := msg.(*testpb.TestRepeatedFields)
// arbitrary logic
signer := testMsg.NullableDontOmitempty[1].Value
return [][]byte{[]byte(signer)}, nil
},
}
}

func TestDefineCustomGetSigners(t *testing.T) {
var interfaceRegistry codectypes.InterfaceRegistry
_, err := simtestutil.SetupAtGenesis(
depinject.Configs(
configurator.NewAppConfig(
configurator.ParamsModule(),
configurator.AuthModule(),
configurator.StakingModule(),
configurator.BankModule(),
configurator.ConsensusModule(),
),
depinject.Supply(log.NewNopLogger()),
depinject.Provide(ProvideCustomGetSigners),
),
&interfaceRegistry,
)
require.NoError(t, err)
require.NotNil(t, interfaceRegistry)

msg := &testpb.TestRepeatedFields{
NullableDontOmitempty: []*testpb.Streng{
{Value: "foo"},
{Value: "bar"},
},
}
signers, err := interfaceRegistry.SigningContext().GetSigners(msg)
require.NoError(t, err)
require.Equal(t, [][]byte{[]byte("bar")}, signers)

// Reset and provider no CustomGetSigners. Consequently, validation will fail and depinject will return an error
_, err = simtestutil.SetupAtGenesis(
depinject.Configs(
configurator.NewAppConfig(
configurator.ParamsModule(),
configurator.AuthModule(),
configurator.StakingModule(),
configurator.BankModule(),
configurator.ConsensusModule(),
),
depinject.Supply(log.NewNopLogger()),
),
&interfaceRegistry,
)
require.ErrorContains(t, err, "use DefineCustomGetSigners")
}
File renamed without changes.
File renamed without changes.
File renamed without changes.
Loading

0 comments on commit bf6edae

Please sign in to comment.