feat(tx): port simappv2 changes (#20648)

Co-authored-by: unknown unknown <unknown@unknown>
Co-authored-by: Julien Robert <julien@rbrt.fr>
This commit is contained in:
testinginprod 2024-06-17 11:54:52 +02:00 committed by GitHub
parent 4b9dca03b4
commit 6d2f6ff068
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
9 changed files with 91 additions and 25 deletions

View File

@ -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.

View File

@ -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)
}

View File

@ -196,18 +196,18 @@ func (m *MockConsensusKeeper) EXPECT() *MockConsensusKeeperMockRecorder {
}
// GetCometInfo mocks base method.
func (m *MockConsensusKeeper) GetCometInfo(arg0 context.Context, arg1 *types0.QueryGetCometInfoRequest) (*types0.QueryGetCometInfoResponse, error) {
func (m *MockConsensusKeeper) GetCometInfo(ctx context.Context, request *types0.QueryGetCometInfoRequest) (*types0.QueryGetCometInfoResponse, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "GetCometInfo", arg0, arg1)
ret := m.ctrl.Call(m, "GetCometInfo", ctx, request)
ret0, _ := ret[0].(*types0.QueryGetCometInfoResponse)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// GetCometInfo indicates an expected call of GetCometInfo.
func (mr *MockConsensusKeeperMockRecorder) GetCometInfo(arg0, arg1 interface{}) *gomock.Call {
func (mr *MockConsensusKeeperMockRecorder) GetCometInfo(ctx, request interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetCometInfo", reflect.TypeOf((*MockConsensusKeeper)(nil).GetCometInfo), arg0, arg1)
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetCometInfo", reflect.TypeOf((*MockConsensusKeeper)(nil).GetCometInfo), ctx, request)
}
// Params mocks base method.

View File

@ -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
}

View File

@ -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()
}

View File

@ -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)
}

View File

@ -3,10 +3,14 @@ package decode
import (
"crypto/sha256"
"errors"
"fmt"
"reflect"
"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"
@ -16,7 +20,8 @@ import (
// 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
@ -30,14 +35,20 @@ type DecodedTx struct {
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.
@ -45,9 +56,12 @@ 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
}
@ -105,16 +119,41 @@ func (d *Decoder) Decode(txBytes []byte) (*DecodedTx, error) {
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())
}
@ -130,6 +169,7 @@ func (d *Decoder) Decode(txBytes []byte) (*DecodedTx, error) {
return &DecodedTx{
Messages: msgs,
DynamicMessages: dynamicMsgs,
Tx: theTx,
TxRaw: &raw,
TxBodyHasUnknownNonCriticals: txBodyHasUnknownNonCriticals,
@ -157,12 +197,7 @@ func (dtx *DecodedTx) GetMessages() ([]transaction.Msg, error) {
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) {

View File

@ -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"
@ -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)
@ -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()))
gogoproto.RegisterType(&testpb.A{}, string((&testpb.A{}).ProtoReflect().Descriptor().FullName()))
testCases := []struct {
name string
msg proto.Message
@ -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)

View File

@ -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"
@ -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)
@ -107,6 +114,7 @@ func FuzzDecode(f *testing.F) {
}
dec, err := NewDecoder(Options{
SigningContext: signingCtx,
ProtoCodec: mockCodec{},
})
if err != nil {
return