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

feat(tx): port simappv2 changes #20648

Merged
merged 10 commits into from
Jun 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 1 addition & 1 deletion simapp/mint_fn.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import (

type MintBankKeeper interface {
MintCoins(ctx context.Context, moduleName string, coins sdk.Coins) error
SendCoinsFromModuleToModule(ctx context.Context, senderModule string, recipientModule string, amt sdk.Coins) error
SendCoinsFromModuleToModule(ctx context.Context, senderModule, recipientModule string, amt sdk.Coins) error
}

// ProvideExampleMintFn returns the function used in x/mint's endblocker to mint new tokens.
Expand Down
2 changes: 1 addition & 1 deletion x/auth/ante/expected_keepers.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,5 +30,5 @@ type FeegrantKeeper interface {

type ConsensusKeeper interface {
Params(context.Context, *consensustypes.QueryParamsRequest) (*consensustypes.QueryParamsResponse, error)
GetCometInfo(context.Context, *consensustypes.QueryGetCometInfoRequest) (*consensustypes.QueryGetCometInfoResponse, error)
GetCometInfo(ctx context.Context, request *consensustypes.QueryGetCometInfoRequest) (*consensustypes.QueryGetCometInfoResponse, error)
}
8 changes: 4 additions & 4 deletions x/auth/ante/testutil/expected_keepers_mocks.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 5 additions & 1 deletion x/auth/tx/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,11 @@ func NewTxConfigWithOptions(protoCodec codec.Codec, configOptions ConfigOptions)
}

if configOptions.ProtoDecoder == nil {
dec, err := txdecode.NewDecoder(txdecode.Options{SigningContext: configOptions.SigningContext})
dec, err := txdecode.NewDecoder(txdecode.Options{
SigningContext: configOptions.SigningContext,
ProtoCodec: protoCodec,
},
)
if err != nil {
return nil, err
}
Expand Down
2 changes: 1 addition & 1 deletion x/auth/tx/gogotx.go
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ func newWrapperFromDecodedTx(addrCodec address.Codec, cdc codec.BinaryCodec, dec

// reflectMsgs
reflectMsgs := make([]protoreflect.Message, len(msgs))
for i, msg := range decodedTx.Messages {
for i, msg := range decodedTx.DynamicMessages {
reflectMsgs[i] = msg.ProtoReflect()
}

Expand Down
9 changes: 8 additions & 1 deletion x/auth/tx/testutil/suite.go
Original file line number Diff line number Diff line change
Expand Up @@ -322,5 +322,12 @@ func (s *TxConfigTestSuite) TestWrapTxBuilder() {
newTxBldr, err := s.TxConfig.WrapTxBuilder(tx)
s.Require().NoError(err)
txBuilder.SetFeePayer(tx.FeePayer()) // NOTE: fee payer will be populated even if empty.
s.Require().Equal(txBuilder.GetTx(), newTxBldr.GetTx())
tx1 := txBuilder.GetTx()
tx2 := newTxBldr.GetTx()

tx1Bytes, err := s.TxConfig.TxEncoder()(tx1)
s.Require().NoError(err)
tx2Bytes, err := s.TxConfig.TxEncoder()(tx2)
s.Require().NoError(err)
s.Require().Equal(tx1Bytes, tx2Bytes)
}
67 changes: 51 additions & 16 deletions x/tx/decode/decode.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,14 @@
import (
"crypto/sha256"
"errors"
"fmt"
"reflect"
Dismissed Show dismissed Hide dismissed
"strings"

"github.com/cosmos/cosmos-proto/anyutil"
gogoproto "github.com/cosmos/gogoproto/proto"
"google.golang.org/protobuf/proto"
"google.golang.org/protobuf/protoadapt"
"google.golang.org/protobuf/reflect/protoreflect"
"google.golang.org/protobuf/types/dynamicpb"

v1beta1 "cosmossdk.io/api/cosmos/tx/v1beta1"
"cosmossdk.io/core/transaction"
Expand All @@ -16,7 +20,8 @@

// DecodedTx contains the decoded transaction, its signers, and other flags.
type DecodedTx struct {
Messages []proto.Message
DynamicMessages []proto.Message
Messages []gogoproto.Message
Tx *v1beta1.Tx
TxRaw *v1beta1.TxRaw
Signers [][]byte
Expand All @@ -30,24 +35,33 @@

var _ transaction.Tx = &DecodedTx{}

type gogoProtoCodec interface {
Unmarshal([]byte, gogoproto.Message) error
}

// Decoder contains the dependencies required for decoding transactions.
type Decoder struct {
signingCtx *signing.Context
codec gogoProtoCodec
}

// Options are options for creating a Decoder.
type Options struct {
SigningContext *signing.Context
ProtoCodec gogoProtoCodec
}

// NewDecoder creates a new Decoder for decoding transactions.
func NewDecoder(options Options) (*Decoder, error) {
if options.SigningContext == nil {
return nil, errors.New("signing context is required")
}

if options.ProtoCodec == nil {
return nil, errors.New("proto codec is required for unmarshalling gogoproto messages")
}
return &Decoder{
signingCtx: options.SigningContext,
codec: options.ProtoCodec,
}, nil
}

Expand Down Expand Up @@ -105,16 +119,41 @@
Signatures: raw.Signatures,
}

var signers [][]byte
var msgs []proto.Message
var (
signers [][]byte
dynamicMsgs []proto.Message
msgs []gogoproto.Message
)
seenSigners := map[string]struct{}{}
for _, anyMsg := range body.Messages {
msg, signerErr := anyutil.Unpack(anyMsg, fileResolver, d.signingCtx.TypeResolver())
if signerErr != nil {
return nil, errorsmod.Wrap(ErrTxDecode, signerErr.Error())
typeURL := strings.TrimPrefix(anyMsg.TypeUrl, "/")

// unmarshal into dynamic message
msgDesc, err := fileResolver.FindDescriptorByName(protoreflect.FullName(typeURL))
if err != nil {
return nil, fmt.Errorf("protoFiles does not have descriptor %s: %w", anyMsg.TypeUrl, err)
}
dynamicMsg := dynamicpb.NewMessageType(msgDesc.(protoreflect.MessageDescriptor)).New().Interface()
err = anyMsg.UnmarshalTo(dynamicMsg)
if err != nil {
return nil, err
}
dynamicMsgs = append(dynamicMsgs, dynamicMsg)

// unmarshal into gogoproto message
gogoType := gogoproto.MessageType(typeURL)
if gogoType == nil {
return nil, fmt.Errorf("cannot find type: %s", anyMsg.TypeUrl)
}
msg := reflect.New(gogoType.Elem()).Interface().(gogoproto.Message)
err = d.codec.Unmarshal(anyMsg.Value, msg)
if err != nil {
return nil, err
}
msgs = append(msgs, msg)
ss, signerErr := d.signingCtx.GetSigners(msg)

// fetch signers with dynamic message
ss, signerErr := d.signingCtx.GetSigners(dynamicMsg)
if signerErr != nil {
return nil, errorsmod.Wrap(ErrTxDecode, signerErr.Error())
}
Expand All @@ -130,6 +169,7 @@

return &DecodedTx{
Messages: msgs,
DynamicMessages: dynamicMsgs,
Tx: theTx,
TxRaw: &raw,
TxBodyHasUnknownNonCriticals: txBodyHasUnknownNonCriticals,
Expand Down Expand Up @@ -157,12 +197,7 @@
return nil, errors.New("messages not available or are nil")
}

msgs := make([]transaction.Msg, len(dtx.Messages))
for i, msg := range dtx.Messages {
msgs[i] = protoadapt.MessageV1Of(msg)
}

return msgs, nil
return dtx.Messages, nil
}

func (dtx *DecodedTx) GetSenders() ([][]byte, error) {
Expand Down
12 changes: 12 additions & 0 deletions x/tx/decode/decode_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"testing"

"github.com/cosmos/cosmos-proto/anyutil"
gogoproto "github.com/cosmos/gogoproto/proto"
"github.com/stretchr/testify/require"
"google.golang.org/protobuf/proto"
"google.golang.org/protobuf/types/known/anypb"
Expand All @@ -21,6 +22,12 @@ import (
"cosmossdk.io/x/tx/signing"
)

type mockCodec struct{}

func (m mockCodec) Unmarshal(bytes []byte, message gogoproto.Message) error {
return gogoproto.Unmarshal(bytes, message)
}

func TestDecode(t *testing.T) {
accSeq := uint64(2)

Expand All @@ -46,9 +53,13 @@ func TestDecode(t *testing.T) {
require.NoError(t, err)
decoder, err := decode.NewDecoder(decode.Options{
SigningContext: signingCtx,
ProtoCodec: mockCodec{},
})
require.NoError(t, err)

gogoproto.RegisterType(&bankv1beta1.MsgSend{}, string((&bankv1beta1.MsgSend{}).ProtoReflect().Descriptor().FullName()))
Copy link
Contributor Author

Choose a reason for hiding this comment

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

this is the test fix to make it work.
the alternative was a really hefty refactor

Copy link
Member

Choose a reason for hiding this comment

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

brilliant 🙌

gogoproto.RegisterType(&testpb.A{}, string((&testpb.A{}).ProtoReflect().Descriptor().FullName()))

testCases := []struct {
name string
msg proto.Message
Expand Down Expand Up @@ -131,6 +142,7 @@ func TestDecodeTxBodyPanic(t *testing.T) {
}
dec, err := decode.NewDecoder(decode.Options{
SigningContext: signingCtx,
ProtoCodec: mockCodec{},
})
if err != nil {
t.Fatal(err)
Expand Down
8 changes: 8 additions & 0 deletions x/tx/decode/fuzz_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"testing"

"github.com/cosmos/cosmos-proto/anyutil"
gogoproto "github.com/cosmos/gogoproto/proto"
fuzz "github.com/google/gofuzz"
"google.golang.org/protobuf/proto"
"google.golang.org/protobuf/types/known/anypb"
Expand All @@ -17,6 +18,12 @@ import (
"cosmossdk.io/x/tx/signing"
)

type mockCodec struct{}

func (m mockCodec) Unmarshal(bytes []byte, message gogoproto.Message) error {
return gogoproto.Unmarshal(bytes, message)
}

var (
accSeq = uint64(2)

Expand Down Expand Up @@ -107,6 +114,7 @@ func FuzzDecode(f *testing.F) {
}
dec, err := NewDecoder(Options{
SigningContext: signingCtx,
ProtoCodec: mockCodec{},
})
if err != nil {
return
Expand Down
Loading