From fe8474e9b419b411cd2f0cf0f33fe4bfc46dc0d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juli=C3=A1n=20Toledano?= Date: Fri, 26 Jul 2024 12:53:32 +0200 Subject: [PATCH] feat: simulate nested messages (#20291) --- CHANGELOG.md | 1 + UPGRADING.md | 33 ++ baseapp/abci_test.go | 236 ++++++++ baseapp/baseapp.go | 63 +- baseapp/options.go | 13 + baseapp/testutil/messages.go | 24 + baseapp/testutil/messages.pb.go | 997 ++++++++++++++++++++++++++++++-- baseapp/testutil/messages.proto | 29 +- baseapp/utils_test.go | 70 +++ simapp/app.go | 4 +- simapp/app_di.go | 1 - 11 files changed, 1416 insertions(+), 55 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b727862bd96a..7473c1561eb7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -42,6 +42,7 @@ Every module contains its own CHANGELOG.md. Please refer to the module you are i ### Features +* (baseapp) [#20291](https://github.com/cosmos/cosmos-sdk/pull/20291) Simulate nested messages. * (tests) [#20013](https://github.com/cosmos/cosmos-sdk/pull/20013) Introduce system tests to run multi node local testnet in CI * (runtime) [#19953](https://github.com/cosmos/cosmos-sdk/pull/19953) Implement `core/transaction.Service` in runtime. * (client) [#19905](https://github.com/cosmos/cosmos-sdk/pull/19905) Add grpc client config to `client.toml`. diff --git a/UPGRADING.md b/UPGRADING.md index 5f96b53ed535..9e57f3a6f9b9 100644 --- a/UPGRADING.md +++ b/UPGRADING.md @@ -5,6 +5,39 @@ Note, always read the **SimApp** section for more information on application wir ## [Unreleased] +### BaseApp + +#### Nested Messages Simulation + +Now it is possible to simulate the nested messages of a message, providing developers with a powerful tool for +testing and predicting the behavior of complex transactions. This feature allows for a more comprehensive +evaluation of gas consumption, state changes, and potential errors that may occur when executing nested +messages. However, it's important to note that while the simulation can provide valuable insights, it does not +guarantee the correct execution of the nested messages in the future. Factors such as changes in the +blockchain state or updates to the protocol could potentially affect the actual execution of these nested +messages when the transaction is finally processed on the network. + +For example, consider a governance proposal that includes nested messages to update multiple protocol +parameters. At the time of simulation, the blockchain state may be suitable for executing all these nested +messages successfully. However, by the time the actual governance proposal is executed (which could be days or +weeks later), the blockchain state might have changed significantly. As a result, while the simulation showed +a successful execution, the actual governance proposal might fail when it's finally processed. + +By default, when simulating transactions, the gas cost of nested messages is not calculated. This means that +only the gas cost of the top-level message is considered. However, this behavior can be customized using the +`SetIncludeNestedMsgsGas` option when building the BaseApp. By providing a list of message types to this option, +you can specify which messages should have their nested message gas costs included in the simulation. This +allows for more accurate gas estimation for transactions involving specific message types that contain nested +messages, while maintaining the default behavior for other message types. + +Here is an example on how `SetIncludeNestedMsgsGas` option could be set to calculate the gas of a gov proposal +nested messages: +```go +baseAppOptions = append(baseAppOptions, baseapp.SetIncludeNestedMsgsGas([]sdk.Message{&gov.MsgSubmitProposal{}})) +// ... +app.App = appBuilder.Build(db, traceStore, baseAppOptions...) +``` + ### SimApp In this section we describe the changes made in Cosmos SDK' SimApp. diff --git a/baseapp/abci_test.go b/baseapp/abci_test.go index 7e08aabfba05..4fea776a8bf7 100644 --- a/baseapp/abci_test.go +++ b/baseapp/abci_test.go @@ -24,6 +24,7 @@ import ( "github.com/cosmos/gogoproto/jsonpb" "github.com/cosmos/gogoproto/proto" gogotypes "github.com/cosmos/gogoproto/types" + any "github.com/cosmos/gogoproto/types/any" "github.com/golang/mock/gomock" "github.com/stretchr/testify/require" @@ -38,6 +39,7 @@ import ( "github.com/cosmos/cosmos-sdk/baseapp" baseapptestutil "github.com/cosmos/cosmos-sdk/baseapp/testutil" "github.com/cosmos/cosmos-sdk/baseapp/testutil/mock" + "github.com/cosmos/cosmos-sdk/codec" cryptocodec "github.com/cosmos/cosmos-sdk/crypto/codec" "github.com/cosmos/cosmos-sdk/testutil" "github.com/cosmos/cosmos-sdk/testutil/testdata" @@ -760,6 +762,240 @@ func TestABCI_FinalizeBlock_MultiMsg(t *testing.T) { require.Equal(t, int64(2), msgCounter2) } +func anyMessage(t *testing.T, cdc codec.Codec, msg *baseapptestutil.MsgSend) *any.Any { + t.Helper() + b, err := cdc.Marshal(msg) + require.NoError(t, err) + return &any.Any{ + TypeUrl: sdk.MsgTypeURL(msg), + Value: b, + } +} + +func TestABCI_Query_SimulateNestedMessagesTx(t *testing.T) { + anteOpt := func(bapp *baseapp.BaseApp) { + bapp.SetAnteHandler(func(ctx sdk.Context, tx sdk.Tx, simulate bool) (newCtx sdk.Context, err error) { + newCtx = ctx.WithGasMeter(storetypes.NewGasMeter(uint64(15))) + return + }) + } + suite := NewBaseAppSuite(t, anteOpt) + + _, err := suite.baseApp.InitChain(&abci.InitChainRequest{ + ConsensusParams: &cmtproto.ConsensusParams{}, + }) + require.NoError(t, err) + + baseapptestutil.RegisterNestedMessagesServer(suite.baseApp.MsgServiceRouter(), NestedMessgesServerImpl{}) + baseapptestutil.RegisterSendServer(suite.baseApp.MsgServiceRouter(), SendServerImpl{}) + + _, _, addr := testdata.KeyTestPubAddr() + _, _, toAddr := testdata.KeyTestPubAddr() + tests := []struct { + name string + message sdk.Msg + wantErr bool + }{ + { + name: "ok nested message", + message: &baseapptestutil.MsgSend{ + From: addr.String(), + To: toAddr.String(), + Amount: "10000stake", + }, + }, + { + name: "different signers", + message: &baseapptestutil.MsgSend{ + From: toAddr.String(), + To: addr.String(), + Amount: "10000stake", + }, + wantErr: true, + }, + { + name: "empty from", + message: &baseapptestutil.MsgSend{ + From: "", + To: toAddr.String(), + Amount: "10000stake", + }, + wantErr: true, + }, + { + name: "empty to", + message: &baseapptestutil.MsgSend{ + From: addr.String(), + To: "", + Amount: "10000stake", + }, + wantErr: true, + }, + { + name: "negative amount", + message: &baseapptestutil.MsgSend{ + From: addr.String(), + To: toAddr.String(), + Amount: "-10000stake", + }, + wantErr: true, + }, + { + name: "with nested messages", + message: &baseapptestutil.MsgNestedMessages{ + Signer: addr.String(), + Messages: []*any.Any{ + anyMessage(t, suite.cdc, &baseapptestutil.MsgSend{ + From: addr.String(), + To: toAddr.String(), + Amount: "10000stake", + }), + }, + }, + }, + { + name: "with invalid nested messages", + message: &baseapptestutil.MsgNestedMessages{ + Signer: addr.String(), + Messages: []*any.Any{ + anyMessage(t, suite.cdc, &baseapptestutil.MsgSend{ + From: "", + To: toAddr.String(), + Amount: "10000stake", + }), + }, + }, + wantErr: true, + }, + { + name: "with different signer ", + message: &baseapptestutil.MsgNestedMessages{ + Signer: addr.String(), + Messages: []*any.Any{ + anyMessage(t, suite.cdc, &baseapptestutil.MsgSend{ + From: toAddr.String(), + To: addr.String(), + Amount: "10000stake", + }), + }, + }, + wantErr: true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + nestedMessages := make([]*any.Any, 1) + b, err := suite.cdc.Marshal(tt.message) + require.NoError(t, err) + nestedMessages[0] = &any.Any{ + TypeUrl: sdk.MsgTypeURL(tt.message), + Value: b, + } + + msg := &baseapptestutil.MsgNestedMessages{ + Messages: nestedMessages, + Signer: addr.String(), + } + + builder := suite.txConfig.NewTxBuilder() + err = builder.SetMsgs(msg) + require.NoError(t, err) + setTxSignature(t, builder, 0) + tx := builder.GetTx() + + txBytes, err := suite.txConfig.TxEncoder()(tx) + require.Nil(t, err) + + _, result, err := suite.baseApp.Simulate(txBytes) + if tt.wantErr { + require.Error(t, err) + require.Nil(t, result) + } else { + require.NoError(t, err) + require.NotNil(t, result) + } + }) + } +} + +func TestABCI_Query_SimulateNestedMessagesGas(t *testing.T) { + anteOpt := func(bapp *baseapp.BaseApp) { + bapp.SetAnteHandler(func(ctx sdk.Context, tx sdk.Tx, simulate bool) (newCtx sdk.Context, err error) { + newCtx = ctx.WithGasMeter(storetypes.NewGasMeter(uint64(10))) + return + }) + } + + _, _, addr := testdata.KeyTestPubAddr() + _, _, toAddr := testdata.KeyTestPubAddr() + + tests := []struct { + name string + suite *BaseAppSuite + message sdk.Msg + consumedGas uint64 + }{ + { + name: "don't add gas", + suite: NewBaseAppSuite(t, anteOpt), + message: &baseapptestutil.MsgSend{ + From: addr.String(), + To: toAddr.String(), + Amount: "10000stake", + }, + consumedGas: 5, + }, + { + name: "add gas", + suite: NewBaseAppSuite(t, anteOpt, baseapp.SetIncludeNestedMsgsGas([]sdk.Msg{&baseapptestutil.MsgNestedMessages{}})), + message: &baseapptestutil.MsgSend{ + From: addr.String(), + To: toAddr.String(), + Amount: "10000stake", + }, + consumedGas: 10, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + _, err := tt.suite.baseApp.InitChain(&abci.InitChainRequest{ + ConsensusParams: &cmtproto.ConsensusParams{}, + }) + require.NoError(t, err) + + baseapptestutil.RegisterNestedMessagesServer(tt.suite.baseApp.MsgServiceRouter(), NestedMessgesServerImpl{}) + baseapptestutil.RegisterSendServer(tt.suite.baseApp.MsgServiceRouter(), SendServerImpl{}) + + nestedMessages := make([]*any.Any, 1) + b, err := tt.suite.cdc.Marshal(tt.message) + require.NoError(t, err) + nestedMessages[0] = &any.Any{ + TypeUrl: sdk.MsgTypeURL(tt.message), + Value: b, + } + + msg := &baseapptestutil.MsgNestedMessages{ + Messages: nestedMessages, + Signer: addr.String(), + } + + builder := tt.suite.txConfig.NewTxBuilder() + err = builder.SetMsgs(msg) + require.NoError(t, err) + setTxSignature(t, builder, 0) + tx := builder.GetTx() + + txBytes, err := tt.suite.txConfig.TxEncoder()(tx) + require.Nil(t, err) + + gas, result, err := tt.suite.baseApp.Simulate(txBytes) + require.NoError(t, err) + require.NotNil(t, result) + require.True(t, gas.GasUsed == tt.consumedGas) + }) + } +} + func TestABCI_Query_SimulateTx(t *testing.T) { gasConsumed := uint64(5) anteOpt := func(bapp *baseapp.BaseApp) { diff --git a/baseapp/baseapp.go b/baseapp/baseapp.go index d23207c667c2..3599a35517ec 100644 --- a/baseapp/baseapp.go +++ b/baseapp/baseapp.go @@ -186,6 +186,9 @@ type BaseApp struct { // including the goroutine handling.This is experimental and must be enabled // by developers. optimisticExec *oe.OptimisticExecution + + // includeNestedMsgsGas holds a set of message types for which gas costs for its nested messages are calculated. + includeNestedMsgsGas map[string]struct{} } // NewBaseApp returns a reference to an initialized BaseApp. It accepts a @@ -233,7 +236,9 @@ func NewBaseApp( if app.interBlockCache != nil { app.cms.SetInterBlockCache(app.interBlockCache) } - + if app.includeNestedMsgsGas == nil { + app.includeNestedMsgsGas = make(map[string]struct{}) + } app.runTxRecoveryMiddleware = newDefaultRecoveryMiddleware() // Initialize with an empty interface registry to avoid nil pointer dereference. @@ -811,6 +816,10 @@ func (app *BaseApp) endBlock(_ context.Context) (sdk.EndBlock, error) { return endblock, nil } +type HasNestedMsgs interface { + GetMsgs() ([]sdk.Msg, error) +} + // runTx processes a transaction within a given execution mode, encoded transaction // bytes, and the decoded transaction itself. All state transitions occur through // a cached Context depending on the mode provided. State only gets persisted @@ -955,6 +964,15 @@ func (app *BaseApp) runTx(mode execMode, txBytes []byte) (gInfo sdk.GasInfo, res result, err = app.runMsgs(runMsgCtx, msgs, reflectMsgs, mode) } + if mode == execModeSimulate { + for _, msg := range msgs { + nestedErr := app.simulateNestedMessages(ctx, msg) + if nestedErr != nil { + return gInfo, nil, anteEvents, nestedErr + } + } + } + // Run optional postHandlers (should run regardless of the execution result). // // Note: If the postHandler fails, we also revert the runMsgs state. @@ -1061,6 +1079,49 @@ func (app *BaseApp) runMsgs(ctx sdk.Context, msgs []sdk.Msg, reflectMsgs []proto }, nil } +// simulateNestedMessages simulates a message nested messages. +func (app *BaseApp) simulateNestedMessages(ctx sdk.Context, msg sdk.Msg) error { + nestedMsgs, ok := msg.(HasNestedMsgs) + if !ok { + return nil + } + + msgs, err := nestedMsgs.GetMsgs() + if err != nil { + return err + } + + if err := validateBasicTxMsgs(app.msgServiceRouter, msgs); err != nil { + return err + } + + for _, msg := range msgs { + err = app.simulateNestedMessages(ctx, msg) + if err != nil { + return err + } + } + + protoMessages := make([]protoreflect.Message, len(msgs)) + for i, msg := range msgs { + _, protoMsg, err := app.cdc.GetMsgSigners(msg) + if err != nil { + return err + } + protoMessages[i] = protoMsg + } + + initialGas := ctx.GasMeter().GasConsumed() + _, err = app.runMsgs(ctx, msgs, protoMessages, execModeSimulate) + if err == nil { + if _, includeGas := app.includeNestedMsgsGas[sdk.MsgTypeURL(msg)]; !includeGas { + consumedGas := ctx.GasMeter().GasConsumed() - initialGas + ctx.GasMeter().RefundGas(consumedGas, "simulation of nested messages") + } + } + return err +} + // makeABCIData generates the Data field to be sent to ABCI Check/DeliverTx. func makeABCIData(msgResponses []*codectypes.Any) ([]byte, error) { return proto.Marshal(&sdk.TxMsgData{MsgResponses: msgResponses}) diff --git a/baseapp/options.go b/baseapp/options.go index 372c2411cf82..bcff418fb8b0 100644 --- a/baseapp/options.go +++ b/baseapp/options.go @@ -119,6 +119,19 @@ func SetOptimisticExecution(opts ...func(*oe.OptimisticExecution)) func(*BaseApp } } +// SetIncludeNestedMsgsGas sets the message types for which gas costs for its nested messages are calculated when simulating. +func SetIncludeNestedMsgsGas(msgs []sdk.Msg) func(*BaseApp) { + return func(app *BaseApp) { + app.includeNestedMsgsGas = make(map[string]struct{}) + for _, msg := range msgs { + if _, ok := msg.(HasNestedMsgs); !ok { + continue + } + app.includeNestedMsgsGas[sdk.MsgTypeURL(msg)] = struct{}{} + } + } +} + func (app *BaseApp) SetName(name string) { if app.sealed { panic("SetName() on sealed BaseApp") diff --git a/baseapp/testutil/messages.go b/baseapp/testutil/messages.go index a4b1cd9abbcb..1bc8a8bd920f 100644 --- a/baseapp/testutil/messages.go +++ b/baseapp/testutil/messages.go @@ -3,6 +3,7 @@ package testutil import ( errorsmod "cosmossdk.io/errors" + codectestutil "github.com/cosmos/cosmos-sdk/codec/testutil" "github.com/cosmos/cosmos-sdk/codec/types" "github.com/cosmos/cosmos-sdk/crypto/codec" sdk "github.com/cosmos/cosmos-sdk/types" @@ -16,10 +17,15 @@ func RegisterInterfaces(registry types.InterfaceRegistry) { &MsgCounter{}, &MsgCounter2{}, &MsgKeyValue{}, + &MsgNestedMessages{}, + &MsgSend{}, ) + msgservice.RegisterMsgServiceDesc(registry, &_Counter_serviceDesc) msgservice.RegisterMsgServiceDesc(registry, &_Counter2_serviceDesc) msgservice.RegisterMsgServiceDesc(registry, &_KeyValue_serviceDesc) + msgservice.RegisterMsgServiceDesc(registry, &_NestedMessages_serviceDesc) + msgservice.RegisterMsgServiceDesc(registry, &_Send_serviceDesc) codec.RegisterInterfaces(registry) } @@ -63,3 +69,21 @@ func (msg *MsgKeyValue) ValidateBasic() error { } return nil } + +func (msg *MsgNestedMessages) GetMsgs() ([]sdk.Msg, error) { + cdc := codectestutil.CodecOptions{}.NewCodec() + RegisterInterfaces(cdc.InterfaceRegistry()) + msgs := make([]sdk.Msg, len(msg.GetMessages())) + for i, m := range msg.GetMessages() { + mm, err := cdc.InterfaceRegistry().Resolve(m.TypeUrl) + if err != nil { + return nil, err + } + err = cdc.UnpackAny(m, &mm) + if err != nil { + return nil, err + } + msgs[i] = mm + } + return msgs, nil +} diff --git a/baseapp/testutil/messages.pb.go b/baseapp/testutil/messages.pb.go index 2884ff0f649a..da3421a020f9 100644 --- a/baseapp/testutil/messages.pb.go +++ b/baseapp/testutil/messages.pb.go @@ -6,11 +6,11 @@ package testutil import ( context "context" fmt "fmt" - _ "github.com/cosmos/cosmos-sdk/codec/types" _ "github.com/cosmos/cosmos-sdk/types/msgservice" _ "github.com/cosmos/gogoproto/gogoproto" grpc1 "github.com/cosmos/gogoproto/grpc" proto "github.com/cosmos/gogoproto/proto" + any "github.com/cosmos/gogoproto/types/any" grpc "google.golang.org/grpc" codes "google.golang.org/grpc/codes" status "google.golang.org/grpc/status" @@ -282,43 +282,240 @@ func (m *MsgCreateKeyValueResponse) XXX_DiscardUnknown() { var xxx_messageInfo_MsgCreateKeyValueResponse proto.InternalMessageInfo +type MsgSend struct { + From string `protobuf:"bytes,1,opt,name=from,proto3" json:"from,omitempty"` + To string `protobuf:"bytes,2,opt,name=to,proto3" json:"to,omitempty"` + Amount string `protobuf:"bytes,3,opt,name=amount,proto3" json:"amount,omitempty"` +} + +func (m *MsgSend) Reset() { *m = MsgSend{} } +func (m *MsgSend) String() string { return proto.CompactTextString(m) } +func (*MsgSend) ProtoMessage() {} +func (*MsgSend) Descriptor() ([]byte, []int) { + return fileDescriptor_4dc296cbfe5ffcd5, []int{5} +} +func (m *MsgSend) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MsgSend) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MsgSend.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *MsgSend) XXX_Merge(src proto.Message) { + xxx_messageInfo_MsgSend.Merge(m, src) +} +func (m *MsgSend) XXX_Size() int { + return m.Size() +} +func (m *MsgSend) XXX_DiscardUnknown() { + xxx_messageInfo_MsgSend.DiscardUnknown(m) +} + +var xxx_messageInfo_MsgSend proto.InternalMessageInfo + +func (m *MsgSend) GetFrom() string { + if m != nil { + return m.From + } + return "" +} + +func (m *MsgSend) GetTo() string { + if m != nil { + return m.To + } + return "" +} + +func (m *MsgSend) GetAmount() string { + if m != nil { + return m.Amount + } + return "" +} + +type MsgSendResponse struct { +} + +func (m *MsgSendResponse) Reset() { *m = MsgSendResponse{} } +func (m *MsgSendResponse) String() string { return proto.CompactTextString(m) } +func (*MsgSendResponse) ProtoMessage() {} +func (*MsgSendResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_4dc296cbfe5ffcd5, []int{6} +} +func (m *MsgSendResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MsgSendResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MsgSendResponse.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *MsgSendResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_MsgSendResponse.Merge(m, src) +} +func (m *MsgSendResponse) XXX_Size() int { + return m.Size() +} +func (m *MsgSendResponse) XXX_DiscardUnknown() { + xxx_messageInfo_MsgSendResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_MsgSendResponse proto.InternalMessageInfo + +type MsgNestedMessages struct { + Messages []*any.Any `protobuf:"bytes,1,rep,name=messages,proto3" json:"messages,omitempty"` + Signer string `protobuf:"bytes,2,opt,name=signer,proto3" json:"signer,omitempty"` +} + +func (m *MsgNestedMessages) Reset() { *m = MsgNestedMessages{} } +func (m *MsgNestedMessages) String() string { return proto.CompactTextString(m) } +func (*MsgNestedMessages) ProtoMessage() {} +func (*MsgNestedMessages) Descriptor() ([]byte, []int) { + return fileDescriptor_4dc296cbfe5ffcd5, []int{7} +} +func (m *MsgNestedMessages) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MsgNestedMessages) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MsgNestedMessages.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *MsgNestedMessages) XXX_Merge(src proto.Message) { + xxx_messageInfo_MsgNestedMessages.Merge(m, src) +} +func (m *MsgNestedMessages) XXX_Size() int { + return m.Size() +} +func (m *MsgNestedMessages) XXX_DiscardUnknown() { + xxx_messageInfo_MsgNestedMessages.DiscardUnknown(m) +} + +var xxx_messageInfo_MsgNestedMessages proto.InternalMessageInfo + +func (m *MsgNestedMessages) GetMessages() []*any.Any { + if m != nil { + return m.Messages + } + return nil +} + +func (m *MsgNestedMessages) GetSigner() string { + if m != nil { + return m.Signer + } + return "" +} + +type MsgCreateNestedMessagesResponse struct { +} + +func (m *MsgCreateNestedMessagesResponse) Reset() { *m = MsgCreateNestedMessagesResponse{} } +func (m *MsgCreateNestedMessagesResponse) String() string { return proto.CompactTextString(m) } +func (*MsgCreateNestedMessagesResponse) ProtoMessage() {} +func (*MsgCreateNestedMessagesResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_4dc296cbfe5ffcd5, []int{8} +} +func (m *MsgCreateNestedMessagesResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MsgCreateNestedMessagesResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MsgCreateNestedMessagesResponse.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *MsgCreateNestedMessagesResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_MsgCreateNestedMessagesResponse.Merge(m, src) +} +func (m *MsgCreateNestedMessagesResponse) XXX_Size() int { + return m.Size() +} +func (m *MsgCreateNestedMessagesResponse) XXX_DiscardUnknown() { + xxx_messageInfo_MsgCreateNestedMessagesResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_MsgCreateNestedMessagesResponse proto.InternalMessageInfo + func init() { proto.RegisterType((*MsgCounter)(nil), "MsgCounter") proto.RegisterType((*MsgCounter2)(nil), "MsgCounter2") proto.RegisterType((*MsgCreateCounterResponse)(nil), "MsgCreateCounterResponse") proto.RegisterType((*MsgKeyValue)(nil), "MsgKeyValue") proto.RegisterType((*MsgCreateKeyValueResponse)(nil), "MsgCreateKeyValueResponse") + proto.RegisterType((*MsgSend)(nil), "MsgSend") + proto.RegisterType((*MsgSendResponse)(nil), "MsgSendResponse") + proto.RegisterType((*MsgNestedMessages)(nil), "MsgNestedMessages") + proto.RegisterType((*MsgCreateNestedMessagesResponse)(nil), "MsgCreateNestedMessagesResponse") } func init() { proto.RegisterFile("messages.proto", fileDescriptor_4dc296cbfe5ffcd5) } var fileDescriptor_4dc296cbfe5ffcd5 = []byte{ - // 390 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x92, 0xcf, 0xaa, 0xd3, 0x40, - 0x14, 0xc6, 0x1b, 0x83, 0x6d, 0x3d, 0xad, 0x5a, 0x42, 0xd1, 0x34, 0x42, 0x28, 0x5d, 0x48, 0x11, - 0x9a, 0xc1, 0xb8, 0x6b, 0x77, 0x8a, 0x54, 0x11, 0x11, 0x22, 0xb8, 0xe8, 0xa6, 0x4c, 0xd2, 0xd3, - 0x69, 0x68, 0x32, 0x13, 0x32, 0x93, 0x42, 0xb7, 0x3e, 0x81, 0x8f, 0xe2, 0x63, 0xb8, 0xec, 0xd2, - 0xa5, 0xb4, 0x0b, 0x5f, 0x43, 0xf2, 0xaf, 0x75, 0x71, 0x7b, 0xb9, 0xab, 0xbb, 0x9a, 0xf3, 0x7d, - 0x87, 0x9c, 0xdf, 0xc9, 0xc7, 0x81, 0x27, 0x31, 0x4a, 0x49, 0x19, 0x4a, 0x27, 0x49, 0x85, 0x12, - 0x56, 0x9f, 0x09, 0x26, 0x8a, 0x92, 0xe4, 0x55, 0xe5, 0x0e, 0x98, 0x10, 0x2c, 0x42, 0x52, 0x28, - 0x3f, 0x5b, 0x13, 0xca, 0xf7, 0x55, 0xeb, 0x79, 0x20, 0x64, 0x2c, 0x24, 0x89, 0x25, 0x23, 0xbb, - 0xd7, 0xf9, 0x53, 0x36, 0x46, 0x12, 0xe0, 0xb3, 0x64, 0xef, 0x44, 0xc6, 0x15, 0xa6, 0x86, 0x09, - 0xad, 0xa0, 0x2c, 0x4d, 0x6d, 0xa8, 0x8d, 0x75, 0xaf, 0x96, 0xc6, 0x4b, 0x78, 0xba, 0xa6, 0x61, - 0xb4, 0x14, 0x7c, 0xb9, 0xa1, 0x7c, 0x15, 0x61, 0x6a, 0x3e, 0x18, 0x6a, 0xe3, 0xb6, 0xf7, 0x38, - 0xb7, 0xbf, 0xf0, 0x0f, 0xa5, 0x69, 0x3c, 0x83, 0xa6, 0x0c, 0x19, 0xc7, 0xd4, 0xd4, 0x87, 0xda, - 0xf8, 0x91, 0x57, 0xa9, 0x69, 0xe7, 0xfb, 0xdf, 0x9f, 0xaf, 0x2a, 0x31, 0x52, 0xd0, 0xb9, 0x40, - 0xdd, 0xfb, 0xa2, 0x5a, 0x60, 0xe6, 0xd4, 0x14, 0xa9, 0xc2, 0x8a, 0xed, 0xa1, 0x4c, 0x04, 0x97, - 0x38, 0x5a, 0x14, 0x1b, 0x7d, 0xc2, 0xfd, 0x37, 0x1a, 0x65, 0x68, 0xf4, 0x40, 0xdf, 0xe2, 0xbe, - 0xd8, 0xa6, 0xeb, 0xe5, 0xa5, 0xd1, 0x87, 0x87, 0xbb, 0xbc, 0x55, 0xf0, 0xbb, 0x5e, 0x29, 0xee, - 0xc6, 0x7d, 0x01, 0x83, 0x33, 0xb7, 0x26, 0xd4, 0x60, 0xf7, 0x3d, 0xb4, 0xea, 0xf0, 0xa7, 0xd0, - 0xfb, 0xc8, 0x83, 0x14, 0x63, 0xe4, 0xaa, 0xf6, 0x3a, 0xce, 0x25, 0x28, 0x6b, 0xe0, 0x5c, 0xdb, - 0xdf, 0x9d, 0x43, 0xfb, 0x1c, 0xe7, 0xec, 0x86, 0x39, 0xdd, 0xff, 0xe6, 0xb8, 0xb7, 0x0d, 0x9a, - 0x41, 0xfb, 0x9c, 0x02, 0x01, 0xfd, 0x2b, 0xaa, 0xf2, 0xdb, 0xda, 0xb4, 0x2c, 0xe7, 0xea, 0xcf, - 0xbc, 0x9d, 0xff, 0x3a, 0xda, 0xda, 0xe1, 0x68, 0x6b, 0x7f, 0x8e, 0xb6, 0xf6, 0xe3, 0x64, 0x37, - 0x0e, 0x27, 0xbb, 0xf1, 0xfb, 0x64, 0x37, 0x16, 0x13, 0x16, 0xaa, 0x4d, 0xe6, 0x3b, 0x81, 0x88, - 0x49, 0x75, 0x8a, 0xe5, 0x33, 0x91, 0xab, 0x2d, 0xf1, 0xa9, 0x44, 0x9a, 0x24, 0x44, 0xa1, 0x54, - 0x99, 0x0a, 0x23, 0xbf, 0x59, 0x1c, 0xe7, 0x9b, 0x7f, 0x01, 0x00, 0x00, 0xff, 0xff, 0x44, 0x91, - 0x2d, 0xb3, 0xf8, 0x02, 0x00, 0x00, + // 535 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x93, 0xcf, 0x6e, 0xd3, 0x40, + 0x10, 0xc6, 0xeb, 0xa4, 0x6d, 0x92, 0x49, 0x48, 0xd3, 0x55, 0x04, 0x8e, 0x91, 0x4c, 0xc8, 0x01, + 0x45, 0x95, 0xba, 0x06, 0x73, 0x4b, 0xc5, 0x01, 0x2a, 0x54, 0x10, 0x0a, 0x45, 0xae, 0xc4, 0xa1, + 0x97, 0xca, 0x49, 0x26, 0x9b, 0x90, 0x78, 0x37, 0xf2, 0xae, 0x2b, 0xe5, 0xca, 0x13, 0xf0, 0x28, + 0x3c, 0x06, 0xc7, 0x1e, 0x39, 0xa2, 0xe4, 0xc0, 0x6b, 0x20, 0xaf, 0xff, 0xb4, 0x14, 0x02, 0x9c, + 0x38, 0xed, 0xcc, 0xac, 0x77, 0x7e, 0xb3, 0xfb, 0x7d, 0x86, 0x7a, 0x80, 0x52, 0xfa, 0x0c, 0x25, + 0x5d, 0x84, 0x42, 0x09, 0xab, 0xc9, 0x04, 0x13, 0x3a, 0x74, 0xe2, 0x28, 0xad, 0xb6, 0x98, 0x10, + 0x6c, 0x8e, 0x8e, 0xce, 0x06, 0xd1, 0xd8, 0xf1, 0xf9, 0x32, 0xdd, 0xba, 0x37, 0x14, 0x32, 0x10, + 0xd2, 0x09, 0x24, 0x73, 0x2e, 0x9f, 0xc4, 0x4b, 0xb2, 0xd1, 0x91, 0x00, 0x7d, 0xc9, 0x8e, 0x45, + 0xc4, 0x15, 0x86, 0xc4, 0x84, 0xd2, 0x30, 0x09, 0x4d, 0xa3, 0x6d, 0x74, 0x8b, 0x5e, 0x96, 0x92, + 0x47, 0xb0, 0x37, 0xf6, 0xa7, 0xf3, 0x0b, 0xc1, 0x2f, 0x26, 0x3e, 0x1f, 0xcd, 0x31, 0x34, 0x0b, + 0x6d, 0xa3, 0x5b, 0xf6, 0xee, 0xc4, 0xe5, 0x53, 0xfe, 0x2a, 0x29, 0x92, 0xbb, 0xb0, 0x2b, 0xa7, + 0x8c, 0x63, 0x68, 0x16, 0xdb, 0x46, 0xb7, 0xe2, 0xa5, 0x59, 0xaf, 0xfa, 0xf1, 0xfb, 0xe7, 0x83, + 0x34, 0xe9, 0x28, 0xa8, 0x5e, 0x43, 0xdd, 0xff, 0x45, 0xb5, 0xc0, 0x8c, 0xa9, 0x21, 0xfa, 0x0a, + 0x53, 0xb6, 0x87, 0x72, 0x21, 0xb8, 0xc4, 0xce, 0xb9, 0x9e, 0xe8, 0x0d, 0x2e, 0xdf, 0xfb, 0xf3, + 0x08, 0x49, 0x03, 0x8a, 0x33, 0x5c, 0xea, 0x69, 0x6a, 0x5e, 0x1c, 0x92, 0x26, 0xec, 0x5c, 0xc6, + 0x5b, 0x9a, 0x5f, 0xf3, 0x92, 0xe4, 0xdf, 0xb8, 0xf7, 0xa1, 0x95, 0x73, 0x33, 0x42, 0x0e, 0x7e, + 0x07, 0xa5, 0xbe, 0x64, 0x67, 0xc8, 0x47, 0x84, 0xc0, 0xf6, 0x38, 0x14, 0x81, 0xa6, 0x56, 0x3c, + 0x1d, 0x93, 0x3a, 0x14, 0x94, 0xd0, 0xcc, 0x8a, 0x57, 0x50, 0x22, 0x06, 0xfa, 0x41, 0x3c, 0x7b, + 0x06, 0x4c, 0xb2, 0x5e, 0x25, 0x06, 0xea, 0x23, 0x9d, 0x7d, 0xd8, 0x4b, 0x3b, 0xe6, 0x90, 0x0f, + 0xb0, 0xdf, 0x97, 0xec, 0x2d, 0x4a, 0x85, 0xa3, 0x7e, 0xea, 0x24, 0xf2, 0x18, 0xca, 0x99, 0xab, + 0x4c, 0xa3, 0x5d, 0xec, 0x56, 0xdd, 0x26, 0x4d, 0x0c, 0x44, 0x33, 0x03, 0xd1, 0xe7, 0x7c, 0xe9, + 0xe5, 0x5f, 0xdd, 0xb8, 0x6d, 0x61, 0xf3, 0x6d, 0x1f, 0xc2, 0x83, 0xfc, 0xb6, 0x3f, 0x13, 0xb3, + 0x71, 0xdc, 0x97, 0x50, 0xca, 0x0c, 0xd7, 0x83, 0xc6, 0x6b, 0x3e, 0x0c, 0x31, 0x40, 0xae, 0xb2, + 0x5a, 0x95, 0x5e, 0x9b, 0xc3, 0x6a, 0xd1, 0x4d, 0x9a, 0xb9, 0x27, 0x50, 0xce, 0x2d, 0x74, 0xf4, + 0x9b, 0x3e, 0xb5, 0x1b, 0x7d, 0xdc, 0x3f, 0x35, 0x3a, 0x82, 0x72, 0xae, 0xbc, 0x03, 0xc5, 0x33, + 0x54, 0xc9, 0xd9, 0xac, 0x68, 0x59, 0x74, 0xa3, 0x80, 0xee, 0x01, 0x6c, 0x6b, 0xf5, 0x3a, 0xe9, + 0x5a, 0xa6, 0xe9, 0xeb, 0x5b, 0x0d, 0x7a, 0x4b, 0x07, 0xf7, 0x14, 0xea, 0xb7, 0x44, 0x78, 0x06, + 0x3b, 0xc7, 0x13, 0x1c, 0xce, 0x08, 0xa1, 0xbf, 0x28, 0x64, 0xb5, 0xe9, 0x5f, 0x5e, 0xf2, 0xc5, + 0xc9, 0x97, 0x95, 0x6d, 0x5c, 0xad, 0x6c, 0xe3, 0xdb, 0xca, 0x36, 0x3e, 0xad, 0xed, 0xad, 0xab, + 0xb5, 0xbd, 0xf5, 0x75, 0x6d, 0x6f, 0x9d, 0x1f, 0xb2, 0xa9, 0x9a, 0x44, 0x03, 0x3a, 0x14, 0x81, + 0x93, 0xfe, 0xfb, 0xc9, 0x72, 0x28, 0x47, 0x33, 0x67, 0xe0, 0x4b, 0xf4, 0x17, 0x0b, 0x47, 0xa1, + 0x54, 0x91, 0x9a, 0xce, 0x07, 0xbb, 0x5a, 0xf2, 0xa7, 0x3f, 0x02, 0x00, 0x00, 0xff, 0xff, 0x12, + 0x9a, 0xa4, 0x74, 0x69, 0x04, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -545,6 +742,150 @@ var _KeyValue_serviceDesc = grpc.ServiceDesc{ Metadata: "messages.proto", } +// SendClient is the client API for Send service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. +type SendClient interface { + Send(ctx context.Context, in *MsgSend, opts ...grpc.CallOption) (*MsgSendResponse, error) +} + +type sendClient struct { + cc grpc1.ClientConn +} + +func NewSendClient(cc grpc1.ClientConn) SendClient { + return &sendClient{cc} +} + +func (c *sendClient) Send(ctx context.Context, in *MsgSend, opts ...grpc.CallOption) (*MsgSendResponse, error) { + out := new(MsgSendResponse) + err := c.cc.Invoke(ctx, "/Send/Send", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// SendServer is the server API for Send service. +type SendServer interface { + Send(context.Context, *MsgSend) (*MsgSendResponse, error) +} + +// UnimplementedSendServer can be embedded to have forward compatible implementations. +type UnimplementedSendServer struct { +} + +func (*UnimplementedSendServer) Send(ctx context.Context, req *MsgSend) (*MsgSendResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method Send not implemented") +} + +func RegisterSendServer(s grpc1.Server, srv SendServer) { + s.RegisterService(&_Send_serviceDesc, srv) +} + +func _Send_Send_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(MsgSend) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(SendServer).Send(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/Send/Send", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(SendServer).Send(ctx, req.(*MsgSend)) + } + return interceptor(ctx, in, info, handler) +} + +var _Send_serviceDesc = grpc.ServiceDesc{ + ServiceName: "Send", + HandlerType: (*SendServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "Send", + Handler: _Send_Send_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "messages.proto", +} + +// NestedMessagesClient is the client API for NestedMessages service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. +type NestedMessagesClient interface { + Check(ctx context.Context, in *MsgNestedMessages, opts ...grpc.CallOption) (*MsgCreateNestedMessagesResponse, error) +} + +type nestedMessagesClient struct { + cc grpc1.ClientConn +} + +func NewNestedMessagesClient(cc grpc1.ClientConn) NestedMessagesClient { + return &nestedMessagesClient{cc} +} + +func (c *nestedMessagesClient) Check(ctx context.Context, in *MsgNestedMessages, opts ...grpc.CallOption) (*MsgCreateNestedMessagesResponse, error) { + out := new(MsgCreateNestedMessagesResponse) + err := c.cc.Invoke(ctx, "/NestedMessages/Check", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// NestedMessagesServer is the server API for NestedMessages service. +type NestedMessagesServer interface { + Check(context.Context, *MsgNestedMessages) (*MsgCreateNestedMessagesResponse, error) +} + +// UnimplementedNestedMessagesServer can be embedded to have forward compatible implementations. +type UnimplementedNestedMessagesServer struct { +} + +func (*UnimplementedNestedMessagesServer) Check(ctx context.Context, req *MsgNestedMessages) (*MsgCreateNestedMessagesResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method Check not implemented") +} + +func RegisterNestedMessagesServer(s grpc1.Server, srv NestedMessagesServer) { + s.RegisterService(&_NestedMessages_serviceDesc, srv) +} + +func _NestedMessages_Check_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(MsgNestedMessages) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(NestedMessagesServer).Check(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/NestedMessages/Check", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(NestedMessagesServer).Check(ctx, req.(*MsgNestedMessages)) + } + return interceptor(ctx, in, info, handler) +} + +var _NestedMessages_serviceDesc = grpc.ServiceDesc{ + ServiceName: "NestedMessages", + HandlerType: (*NestedMessagesServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "Check", + Handler: _NestedMessages_Check_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "messages.proto", +} + func (m *MsgCounter) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) @@ -725,39 +1066,173 @@ func (m *MsgCreateKeyValueResponse) MarshalToSizedBuffer(dAtA []byte) (int, erro return len(dAtA) - i, nil } -func encodeVarintMessages(dAtA []byte, offset int, v uint64) int { - offset -= sovMessages(v) - base := offset - for v >= 1<<7 { - dAtA[offset] = uint8(v&0x7f | 0x80) - v >>= 7 - offset++ +func (m *MsgSend) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err } - dAtA[offset] = uint8(v) - return base + return dAtA[:n], nil } -func (m *MsgCounter) Size() (n int) { - if m == nil { - return 0 - } + +func (m *MsgSend) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MsgSend) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i var l int _ = l - if m.Counter != 0 { - n += 1 + sovMessages(uint64(m.Counter)) + if len(m.Amount) > 0 { + i -= len(m.Amount) + copy(dAtA[i:], m.Amount) + i = encodeVarintMessages(dAtA, i, uint64(len(m.Amount))) + i-- + dAtA[i] = 0x1a } - if m.FailOnHandler { - n += 2 + if len(m.To) > 0 { + i -= len(m.To) + copy(dAtA[i:], m.To) + i = encodeVarintMessages(dAtA, i, uint64(len(m.To))) + i-- + dAtA[i] = 0x12 } - l = len(m.Signer) - if l > 0 { - n += 1 + l + sovMessages(uint64(l)) + if len(m.From) > 0 { + i -= len(m.From) + copy(dAtA[i:], m.From) + i = encodeVarintMessages(dAtA, i, uint64(len(m.From))) + i-- + dAtA[i] = 0xa } - return n + return len(dAtA) - i, nil } -func (m *MsgCounter2) Size() (n int) { - if m == nil { - return 0 +func (m *MsgSendResponse) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *MsgSendResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MsgSendResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + return len(dAtA) - i, nil +} + +func (m *MsgNestedMessages) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *MsgNestedMessages) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MsgNestedMessages) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Signer) > 0 { + i -= len(m.Signer) + copy(dAtA[i:], m.Signer) + i = encodeVarintMessages(dAtA, i, uint64(len(m.Signer))) + i-- + dAtA[i] = 0x12 + } + if len(m.Messages) > 0 { + for iNdEx := len(m.Messages) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Messages[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintMessages(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + } + return len(dAtA) - i, nil +} + +func (m *MsgCreateNestedMessagesResponse) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *MsgCreateNestedMessagesResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MsgCreateNestedMessagesResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + return len(dAtA) - i, nil +} + +func encodeVarintMessages(dAtA []byte, offset int, v uint64) int { + offset -= sovMessages(v) + base := offset + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return base +} +func (m *MsgCounter) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Counter != 0 { + n += 1 + sovMessages(uint64(m.Counter)) + } + if m.FailOnHandler { + n += 2 + } + l = len(m.Signer) + if l > 0 { + n += 1 + l + sovMessages(uint64(l)) + } + return n +} + +func (m *MsgCounter2) Size() (n int) { + if m == nil { + return 0 } var l int _ = l @@ -813,6 +1288,64 @@ func (m *MsgCreateKeyValueResponse) Size() (n int) { return n } +func (m *MsgSend) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.From) + if l > 0 { + n += 1 + l + sovMessages(uint64(l)) + } + l = len(m.To) + if l > 0 { + n += 1 + l + sovMessages(uint64(l)) + } + l = len(m.Amount) + if l > 0 { + n += 1 + l + sovMessages(uint64(l)) + } + return n +} + +func (m *MsgSendResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + return n +} + +func (m *MsgNestedMessages) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if len(m.Messages) > 0 { + for _, e := range m.Messages { + l = e.Size() + n += 1 + l + sovMessages(uint64(l)) + } + } + l = len(m.Signer) + if l > 0 { + n += 1 + l + sovMessages(uint64(l)) + } + return n +} + +func (m *MsgCreateNestedMessagesResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + return n +} + func sovMessages(x uint64) (n int) { return (math_bits.Len64(x|1) + 6) / 7 } @@ -1311,6 +1844,368 @@ func (m *MsgCreateKeyValueResponse) Unmarshal(dAtA []byte) error { } return nil } +func (m *MsgSend) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMessages + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: MsgSend: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MsgSend: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field From", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMessages + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthMessages + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthMessages + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.From = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field To", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMessages + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthMessages + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthMessages + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.To = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Amount", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMessages + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthMessages + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthMessages + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Amount = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipMessages(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthMessages + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *MsgSendResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMessages + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: MsgSendResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MsgSendResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + default: + iNdEx = preIndex + skippy, err := skipMessages(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthMessages + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *MsgNestedMessages) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMessages + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: MsgNestedMessages: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MsgNestedMessages: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Messages", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMessages + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthMessages + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthMessages + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Messages = append(m.Messages, &any.Any{}) + if err := m.Messages[len(m.Messages)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Signer", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMessages + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthMessages + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthMessages + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Signer = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipMessages(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthMessages + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *MsgCreateNestedMessagesResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMessages + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: MsgCreateNestedMessagesResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MsgCreateNestedMessagesResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + default: + iNdEx = preIndex + skippy, err := skipMessages(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthMessages + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} func skipMessages(dAtA []byte) (n int, err error) { l := len(dAtA) iNdEx := 0 diff --git a/baseapp/testutil/messages.proto b/baseapp/testutil/messages.proto index d2b25d24c117..2e0cfd15195f 100644 --- a/baseapp/testutil/messages.proto +++ b/baseapp/testutil/messages.proto @@ -34,6 +34,25 @@ message MsgKeyValue { message MsgCreateKeyValueResponse {} +message MsgSend { + option (cosmos.msg.v1.signer) = "from"; + + string from = 1; + string to = 2; + string amount = 3; +} + +message MsgSendResponse {} + +message MsgNestedMessages { + option (cosmos.msg.v1.signer) = "signer"; + + repeated google.protobuf.Any messages = 1; + string signer = 2; +} + +message MsgCreateNestedMessagesResponse {} + service Counter { rpc IncrementCounter(MsgCounter) returns (MsgCreateCounterResponse); } @@ -44,4 +63,12 @@ service Counter2 { service KeyValue { rpc Set(MsgKeyValue) returns (MsgCreateKeyValueResponse); -} \ No newline at end of file +} + +service Send { + rpc Send(MsgSend) returns (MsgSendResponse); +} + +service NestedMessages { + rpc Check(MsgNestedMessages) returns (MsgCreateNestedMessagesResponse); +} diff --git a/baseapp/utils_test.go b/baseapp/utils_test.go index f95ac16c9f78..27668ce590c5 100644 --- a/baseapp/utils_test.go +++ b/baseapp/utils_test.go @@ -32,6 +32,7 @@ import ( baseapptestutil "github.com/cosmos/cosmos-sdk/baseapp/testutil" "github.com/cosmos/cosmos-sdk/client" addresscodec "github.com/cosmos/cosmos-sdk/codec/address" + codectestutil "github.com/cosmos/cosmos-sdk/codec/testutil" "github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1" "github.com/cosmos/cosmos-sdk/testutil/testdata" sdk "github.com/cosmos/cosmos-sdk/types" @@ -375,3 +376,72 @@ func wonkyMsg(t *testing.T, cfg client.TxConfig, tx signing.Tx) signing.Tx { require.NoError(t, err) return builder.GetTx() } + +type SendServerImpl struct { + gas uint64 +} + +func (s SendServerImpl) Send(ctx context.Context, send *baseapptestutil.MsgSend) (*baseapptestutil.MsgSendResponse, error) { + sdkCtx := sdk.UnwrapSDKContext(ctx) + if send.From == "" { + return nil, errors.New("from address cannot be empty") + } + if send.To == "" { + return nil, errors.New("to address cannot be empty") + } + + _, err := sdk.ParseCoinNormalized(send.Amount) + if err != nil { + return nil, err + } + gas := s.gas + if gas == 0 { + gas = 5 + } + sdkCtx.GasMeter().ConsumeGas(gas, "send test") + return &baseapptestutil.MsgSendResponse{}, nil +} + +type NestedMessgesServerImpl struct { + gas uint64 +} + +func (n NestedMessgesServerImpl) Check(ctx context.Context, message *baseapptestutil.MsgNestedMessages) (*baseapptestutil.MsgCreateNestedMessagesResponse, error) { + sdkCtx := sdk.UnwrapSDKContext(ctx) + cdc := codectestutil.CodecOptions{}.NewCodec() + baseapptestutil.RegisterInterfaces(cdc.InterfaceRegistry()) + + signer, _, err := cdc.GetMsgSigners(message) + if err != nil { + return nil, err + } + if len(signer) != 1 { + return nil, fmt.Errorf("expected 1 signer, got %d", len(signer)) + } + + msgs, err := message.GetMsgs() + if err != nil { + return nil, err + } + + for _, msg := range msgs { + s, _, err := cdc.GetMsgSigners(msg) + if err != nil { + return nil, err + } + if len(s) != 1 { + return nil, fmt.Errorf("expected 1 signer, got %d", len(s)) + } + if !bytes.Equal(signer[0], s[0]) { + return nil, errors.New("signer does not match") + } + + } + + gas := n.gas + if gas == 0 { + gas = 5 + } + sdkCtx.GasMeter().ConsumeGas(gas, "nested messages test") + return nil, nil +} diff --git a/simapp/app.go b/simapp/app.go index df3e524922d6..443a47054917 100644 --- a/simapp/app.go +++ b/simapp/app.go @@ -66,6 +66,7 @@ import ( "cosmossdk.io/x/gov" govkeeper "cosmossdk.io/x/gov/keeper" govtypes "cosmossdk.io/x/gov/types" + govv1 "cosmossdk.io/x/gov/types/v1" govv1beta1 "cosmossdk.io/x/gov/types/v1beta1" "cosmossdk.io/x/group" groupkeeper "cosmossdk.io/x/group/keeper" @@ -247,7 +248,8 @@ func NewSimApp( voteExtHandler := NewVoteExtensionHandler() voteExtHandler.SetHandlers(bApp) } - baseAppOptions = append(baseAppOptions, voteExtOp, baseapp.SetOptimisticExecution()) + baseAppOptions = append(baseAppOptions, voteExtOp, baseapp.SetOptimisticExecution(), + baseapp.SetIncludeNestedMsgsGas([]sdk.Msg{&govv1.MsgSubmitProposal{}})) bApp := baseapp.NewBaseApp(appName, logger, db, txConfig.TxDecoder(), baseAppOptions...) bApp.SetCommitMultiStoreTracer(traceStore) diff --git a/simapp/app_di.go b/simapp/app_di.go index 52c9917fd186..63beee09ab7e 100644 --- a/simapp/app_di.go +++ b/simapp/app_di.go @@ -137,7 +137,6 @@ func NewSimApp( appOpts, // supply the logger logger, - // ADVANCED CONFIGURATION //