From eb80a1a141c92fcaccd712d90bff59e30bb238a9 Mon Sep 17 00:00:00 2001 From: Matt Kocubinski Date: Mon, 24 Apr 2023 20:50:42 -0500 Subject: [PATCH] feat(x/tx): API improvements (#15871) --- x/tx/signing/handler_map.go | 19 ++++++++++-- x/tx/signing/handler_map_test.go | 50 ++++++++++++++++++++++++++++++++ x/tx/signing/textual/handler.go | 10 ++++--- 3 files changed, 73 insertions(+), 6 deletions(-) create mode 100644 x/tx/signing/handler_map_test.go diff --git a/x/tx/signing/handler_map.go b/x/tx/signing/handler_map.go index 076a2166892c0..98238a51d047f 100644 --- a/x/tx/signing/handler_map.go +++ b/x/tx/signing/handler_map.go @@ -11,17 +11,27 @@ import ( // based on sign mode. type HandlerMap struct { signModeHandlers map[signingv1beta1.SignMode]SignModeHandler + defaultMode signingv1beta1.SignMode modes []signingv1beta1.SignMode } -// NewHandlerMap constructs a new sign mode handler map. +// NewHandlerMap constructs a new sign mode handler map. The first handler is used as the default. func NewHandlerMap(handlers ...SignModeHandler) *HandlerMap { + if len(handlers) == 0 { + panic("no handlers") + } res := &HandlerMap{ signModeHandlers: map[signingv1beta1.SignMode]SignModeHandler{}, } - for _, handler := range handlers { + for i, handler := range handlers { + if handler == nil { + panic("nil handler") + } mode := handler.Mode() + if i == 0 { + res.defaultMode = mode + } res.signModeHandlers[mode] = handler res.modes = append(res.modes, mode) } @@ -34,6 +44,11 @@ func (h *HandlerMap) SupportedModes() []signingv1beta1.SignMode { return h.modes } +// DefaultMode returns the default mode for this handler map. +func (h *HandlerMap) DefaultMode() signingv1beta1.SignMode { + return h.defaultMode +} + // GetSignBytes returns the sign bytes for the transaction for the requested mode. func (h *HandlerMap) GetSignBytes(ctx context.Context, signMode signingv1beta1.SignMode, signerData SignerData, txData TxData) ([]byte, error) { handler, ok := h.signModeHandlers[signMode] diff --git a/x/tx/signing/handler_map_test.go b/x/tx/signing/handler_map_test.go new file mode 100644 index 0000000000000..a937ac643ee04 --- /dev/null +++ b/x/tx/signing/handler_map_test.go @@ -0,0 +1,50 @@ +package signing_test + +import ( + "context" + "testing" + + "github.com/stretchr/testify/require" + + signingv1beta1 "cosmossdk.io/api/cosmos/tx/signing/v1beta1" + "cosmossdk.io/x/tx/signing" +) + +var ( + _ signing.SignModeHandler = directHandler{} + _ signing.SignModeHandler = aminoJSONHandler{} +) + +type directHandler struct{} + +func (s directHandler) Mode() signingv1beta1.SignMode { + return signingv1beta1.SignMode_SIGN_MODE_DIRECT +} + +func (s directHandler) GetSignBytes(_ context.Context, _ signing.SignerData, _ signing.TxData) ([]byte, error) { + panic("not implemented") +} + +type aminoJSONHandler struct{} + +func (s aminoJSONHandler) Mode() signingv1beta1.SignMode { + return signingv1beta1.SignMode_SIGN_MODE_LEGACY_AMINO_JSON +} + +func (s aminoJSONHandler) GetSignBytes(_ context.Context, _ signing.SignerData, _ signing.TxData) ([]byte, error) { + panic("not implemented") +} + +func TestNewHandlerMap(t *testing.T) { + require.PanicsWithValue(t, "nil handler", func() { + signing.NewHandlerMap(nil) + }) + require.PanicsWithValue(t, "no handlers", func() { + signing.NewHandlerMap() + }) + dh := directHandler{} + ah := aminoJSONHandler{} + handlerMap := signing.NewHandlerMap(dh, aminoJSONHandler{}) + require.Equal(t, dh.Mode(), handlerMap.DefaultMode()) + require.NotEqual(t, ah.Mode(), handlerMap.DefaultMode()) +} diff --git a/x/tx/signing/textual/handler.go b/x/tx/signing/textual/handler.go index a6e8d12d02443..97b6e3a752df0 100644 --- a/x/tx/signing/textual/handler.go +++ b/x/tx/signing/textual/handler.go @@ -6,7 +6,6 @@ import ( "fmt" "reflect" - signingv1beta1 "cosmossdk.io/api/cosmos/tx/signing/v1beta1" "google.golang.org/protobuf/proto" "google.golang.org/protobuf/reflect/protoreflect" "google.golang.org/protobuf/reflect/protoregistry" @@ -14,9 +13,12 @@ import ( "google.golang.org/protobuf/types/known/durationpb" "google.golang.org/protobuf/types/known/timestamppb" + signingv1beta1 "cosmossdk.io/api/cosmos/tx/signing/v1beta1" + + cosmos_proto "github.com/cosmos/cosmos-proto" + bankv1beta1 "cosmossdk.io/api/cosmos/bank/v1beta1" basev1beta1 "cosmossdk.io/api/cosmos/base/v1beta1" - cosmos_proto "github.com/cosmos/cosmos-proto" "cosmossdk.io/x/tx/signing" "cosmossdk.io/x/tx/signing/textual/internal/textualpb" @@ -41,7 +43,7 @@ type SignModeOptions struct { // FileResolver are the protobuf files to use for resolving message // descriptors. If it is nil, the global protobuf registry will be used. - FileResolver *protoregistry.Files + FileResolver signing.ProtoFileResolver // TypeResolver are the protobuf type resolvers to use for resolving message // types. If it is nil, then a dynamicpb will be used on top of FileResolver. @@ -51,7 +53,7 @@ type SignModeOptions struct { // SignModeHandler holds the configuration for dispatching // to specific value renderers for SIGN_MODE_TEXTUAL. type SignModeHandler struct { - fileResolver *protoregistry.Files + fileResolver signing.ProtoFileResolver typeResolver protoregistry.MessageTypeResolver coinMetadataQuerier CoinMetadataQueryFn // scalars defines a registry for Cosmos scalars.