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

Extend ClientConn on TxBuilder #7630

Closed
wants to merge 26 commits into from
Closed
Show file tree
Hide file tree
Changes from 25 commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
9c8486d
Add invoke & NewStream
amaury1093 Oct 22, 2020
2c36489
Remove validate basic
amaury1093 Oct 22, 2020
097c13f
Update test
amaury1093 Oct 22, 2020
b0e89dc
WIP
amaury1093 Oct 22, 2020
55c4a88
Merge branch 'master' of ssh://github.com/cosmos/cosmos-sdk into am-7…
amaury1093 Oct 23, 2020
7b44e68
NewAnyWithWithTypeURL
amaury1093 Oct 23, 2020
7b1e26a
Add todo comment for amino
amaury1093 Oct 23, 2020
2306164
Merge branch 'master' of ssh://github.com/cosmos/cosmos-sdk into am-7…
amaury1093 Oct 23, 2020
12cba1e
Add Changelog
amaury1093 Oct 23, 2020
73af333
Remove println
amaury1093 Oct 23, 2020
383b3e8
Update codec/types/any.go
amaury1093 Oct 23, 2020
24cdb72
Add AppendMsgs
amaury1093 Oct 23, 2020
70c0ebf
Rename SetMsgs to AppendMsgs
amaury1093 Oct 23, 2020
626319a
Merge branch 'am-7541-txbuilder' of ssh://github.com/cosmos/cosmos-sd…
amaury1093 Oct 23, 2020
3b75af0
Merge branch 'master' into am-7541-txbuilder
Oct 23, 2020
9a68044
Merge branch 'master' of ssh://github.com/cosmos/cosmos-sdk into am-7…
amaury1093 Oct 26, 2020
92679a4
Address review comments
amaury1093 Oct 26, 2020
4e2f3a5
Add comment
amaury1093 Oct 26, 2020
dc1613b
Typo
amaury1093 Oct 26, 2020
e5c6106
Merge branch 'master' into am-7541-txbuilder
amaury1093 Oct 26, 2020
b6209de
Merge branch 'master' of ssh://github.com/cosmos/cosmos-sdk into am-7…
amaury1093 Dec 11, 2020
173b75d
Use SetMsgs
amaury1093 Dec 11, 2020
7b9da51
remove AppendMsg
amaury1093 Dec 11, 2020
8083644
Add comments and CHANHGELOG
amaury1093 Dec 11, 2020
ade84b5
Add validate basic
amaury1093 Dec 11, 2020
7afe557
Merge branch 'master' of ssh://github.com/cosmos/cosmos-sdk into am-7…
amaury1093 Dec 15, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ Ref: https://keepachangelog.com/en/1.0.0/
* Updated iavl dependency to v0.15-rc2
* (version) [\#7848](https://github.com/cosmos/cosmos-sdk/pull/7848) [\#7941](https://github.com/cosmos/cosmos-sdk/pull/7941) `version --long` output now shows the list of build dependencies and replaced build dependencies.
* (x/genutil) [\#8099](https://github.com/cosmos/cosmos-sdk/pull/8099) `init` now supports a `--recover` flag to recover the private validator key from a given mnemonic
* (tx) [\#7630](https://github.com/cosmos/cosmos-sdk/pull/7630) TxBuilder now extends gogogrpc.ClientConn to support ADR-031 service Msgs.

### State Machine Breaking Changes

Expand Down
3 changes: 3 additions & 0 deletions client/tx_config.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package client

import (
gogogrpc "github.com/gogo/protobuf/grpc"

sdk "github.com/cosmos/cosmos-sdk/types"
signingtypes "github.com/cosmos/cosmos-sdk/types/tx/signing"
"github.com/cosmos/cosmos-sdk/x/auth/signing"
Expand Down Expand Up @@ -34,6 +36,7 @@ type (
// signatures, and provide canonical bytes to sign over. The transaction must
// also know how to encode itself.
TxBuilder interface {
gogogrpc.ClientConn
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think an update to ADR 020 is really needed, wdyt?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably not. But just wondering is it better to change the interface, or create a separate struct that implements ClientConn wraps TxBuilder?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like the idea of creating ClientConn. I was confused with the Invoke method initially. Maybe we can call the new interface: MsgSrvClient?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ping?

Copy link
Contributor Author

@amaury1093 amaury1093 Dec 15, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure here. Are you proposing:

type MsgSrvClient struct {
  txBuilder TxBuilder
}

var _ gogogrpc.ClientConn = MsgSrvClient{}

? I feel yet another struct creates more confusion. At some point we should revisit #7630 (comment), which imo is the ideal way forward.

GetTx() signing.Tx

SetMsgs(msgs ...sdk.Msg) error
Expand Down
31 changes: 26 additions & 5 deletions codec/types/any.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,11 +69,25 @@ func NewAnyWithValue(value proto.Message) (*Any, error) {
return any, nil
}

// Pack packs the value x in the Any or returns an error. This also caches
// the packed value so that it can be retrieved from GetCachedValue without
// unmarshaling
func (any *Any) Pack(x proto.Message) error {
any.TypeUrl = "/" + proto.MessageName(x)
// NewAnyWithTypeURL constructs a new Any packed with the value provided
// and a custom TypeURL. It returns an error if that value couldn't be packed.
// This also cachesthe packed value so that it can be retrieved from
// GetCachedValue without unmarshaling.
//
// Ex:
// This will allow us to pack service methods in Any's using the full method name
// as the type URL and the request body as the value.
func NewAnyWithTypeURL(typeURL string, value proto.Message) (*Any, error) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This function looks dangerous.

Is the protobuf generated code already providing it? Maybe there is a method already for this?

Copy link
Contributor Author

@amaury1093 amaury1093 Oct 26, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is the protobuf generated code already providing it? Maybe there is a method already for this?

I don't think so, because we have our own implementation of Any.

any := &Any{}

return any, any.packWithCustomTypeURL(typeURL, value)
}
amaury1093 marked this conversation as resolved.
Show resolved Hide resolved

// PackWithCustomTypeURL packs the value x in the Any or returns an error,
// allowing for a custom TypeUrl. This also caches the packed value so that it
// can be retrieved fromGetCachedValue without unmarshaling.
func (any *Any) packWithCustomTypeURL(typeURL string, x proto.Message) error {
any.TypeUrl = typeURL
bz, err := proto.Marshal(x)
if err != nil {
return err
Expand All @@ -85,6 +99,13 @@ func (any *Any) Pack(x proto.Message) error {
return nil
}

// Pack packs the value x in the Any or returns an error. This also caches
// the packed value so that it can be retrieved from GetCachedValue without
// unmarshaling
func (any *Any) Pack(x proto.Message) error {
return any.packWithCustomTypeURL("/"+proto.MessageName(x), x)
}

// UnsafePackAny packs the value x in the Any and instead of returning the error
// in the case of a packing failure, keeps the cached value. This should only
// be used in situations where compatibility is needed with amino. Amino-only
Expand Down
40 changes: 40 additions & 0 deletions x/auth/legacy/legacytx/msg_service.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package legacytx

import (
gocontext "context"
"fmt"

"google.golang.org/grpc"

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

// Invoke implements the grpc ClientConn.Invoke method. This is so that we can
// use ADR-031 service `Msg`s with StdTxBuilder. Invoking this method will
// **append** the service Msg into the TxBuilder's Msgs array.
// TODO Full amino support still needs to be added as part of https://github.com/cosmos/cosmos-sdk/issues/7541.
amaury1093 marked this conversation as resolved.
Show resolved Hide resolved
Comment on lines +13 to +16
Copy link
Contributor Author

@amaury1093 amaury1093 Jan 11, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This PR was originally set up in #7541. It introduces a clunky UX to manage service Msgs with TxBuilder, see #7630 (comment). It should be ultimately replaced by a custom code generator #8270.

However, as I understand, #8270 is targetted for 0.42, whereas this PR might be useful for 0.41's x/fee_grant and x/authz (see #8061 (comment), #7629 (comment), both use a temporary ServiceMsgClientConn struct for now).

Should we:

  1. Merge this, and have a slightly clunky txBuilder for now?
  2. Close this, use temporary ServiceMsgClientConn wherever we need service Msgs, and wait for Custom protobuf service code generator #8270?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Talking offline with the Regen team, I'll close this PR.

func (s *StdTxBuilder) Invoke(_ gocontext.Context, method string, args, reply interface{}, _ ...grpc.CallOption) error {
req, ok := args.(sdk.MsgRequest)
if !ok {
return sdkerrors.Wrapf(sdkerrors.ErrInvalidType, "%T should implement %T", args, (*sdk.MsgRequest)(nil))
}

err := req.ValidateBasic()
if err != nil {
return err
}

msgs := append(s.Msgs, sdk.ServiceMsg{
MethodName: method,
Request: req,
})
s.SetMsgs(msgs...)

return nil
}

// NewStream implements the grpc ClientConn.NewStream method.
func (s *StdTxBuilder) NewStream(gocontext.Context, *grpc.StreamDesc, string, ...grpc.CallOption) (grpc.ClientStream, error) {
return nil, fmt.Errorf("not supported")
}
7 changes: 2 additions & 5 deletions x/auth/tx/builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,7 @@ func (w *wrapper) GetSignaturesV2() ([]signing.SignatureV2, error) {
return res, nil
}

// SetMsgs implemented the TxBuilder.SetMsgs method.
func (w *wrapper) SetMsgs(msgs ...sdk.Msg) error {
anys := make([]*codectypes.Any, len(msgs))

Expand All @@ -205,14 +206,10 @@ func (w *wrapper) SetMsgs(msgs ...sdk.Msg) error {
switch msg := msg.(type) {
case sdk.ServiceMsg:
{
bz, err := proto.Marshal(msg.Request)
anys[i], err = codectypes.NewAnyWithTypeURL(msg.MethodName, msg.Request)
if err != nil {
return err
}
anys[i] = &codectypes.Any{
TypeUrl: msg.MethodName,
Value: bz,
}
}
default:
{
Expand Down
39 changes: 39 additions & 0 deletions x/auth/tx/msg_service.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package tx

import (
gocontext "context"
"fmt"

"google.golang.org/grpc"

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

// Invoke implements the grpc ClientConn.Invoke method. This is so that we can
// use ADR-031 service `Msg`s with wrapper. Invoking this method will
// **append** the service Msg into the TxBuilder's Msgs array.
func (w *wrapper) Invoke(_ gocontext.Context, method string, args, reply interface{}, _ ...grpc.CallOption) error {
req, ok := args.(sdk.MsgRequest)
amaury1093 marked this conversation as resolved.
Show resolved Hide resolved
if !ok {
return sdkerrors.Wrapf(sdkerrors.ErrInvalidType, "%T should implement %T", args, (*sdk.MsgRequest)(nil))
}

err := req.ValidateBasic()
if err != nil {
return err
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

shouldn't we use sdkerrors.Wrapf here?

Copy link
Contributor Author

@amaury1093 amaury1093 Dec 15, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thumbed up, but maybe it's not necessary. err should already be a SDK error. I used sdkerrors.Wrapf 3 lines above because there's no underlying error.

}

msgs := append(w.GetMsgs(), sdk.ServiceMsg{
MethodName: method,
Request: req,
})
w.SetMsgs(msgs...)

return nil
}

// NewStream implements the grpc ClientConn.NewStream method.
func (w *wrapper) NewStream(gocontext.Context, *grpc.StreamDesc, string, ...grpc.CallOption) (grpc.ClientStream, error) {
return nil, fmt.Errorf("not supported")
}