diff --git a/CHANGELOG.md b/CHANGELOG.md index fd6ba83dd46b..ef865bda5c3d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -51,11 +51,13 @@ Ref: https://keepachangelog.com/en/1.0.0/ * `Validator.ConsensusPubkey` type changed from `string` to `codectypes.Any`. * `MsgCreateValidator.Pubkey` type changed from `string` to `codectypes.Any`. * Deprecating and renaming `MakeEncodingConfig` to `MakeTestEncodingConfig` (both in `simapp` and `simapp/params` packages). +* (tx) [\#7688](https://github.com/cosmos/cosmos-sdk/pull/7688) The gRPC simulate service method has been moved from `cosmos.base.v1beta1.simulate` to `cosmos.tx.v1beta1`, as a method in the Tx service. ### Features * (codec) [\#7519](https://github.com/cosmos/cosmos-sdk/pull/7519) `InterfaceRegistry` now inherits `jsonpb.AnyResolver`, and has a `RegisterCustomTypeURL` method to support ADR 031 packing of `Any`s. `AnyResolver` is now a required parameter to `RejectUnknownFields`. * (baseapp) [\#7519](https://github.com/cosmos/cosmos-sdk/pull/7519) Add `ServiceMsgRouter` to BaseApp to handle routing of protobuf service `Msg`s. The two new types defined in ADR 031, `sdk.ServiceMsg` and `sdk.MsgRequest` are introduced with this router. +* (tx) [\#7688](https://github.com/cosmos/cosmos-sdk/pull/7688) Add a new Tx gRPC service with methods `Simulate` and `GetTx` (by hash). ### Bug Fixes diff --git a/baseapp/grpcrouter.go b/baseapp/grpcrouter.go index 566333b2a4b3..de553589c975 100644 --- a/baseapp/grpcrouter.go +++ b/baseapp/grpcrouter.go @@ -10,7 +10,6 @@ import ( "google.golang.org/grpc/encoding/proto" "github.com/cosmos/cosmos-sdk/client/grpc/reflection" - "github.com/cosmos/cosmos-sdk/client/grpc/simulate" codectypes "github.com/cosmos/cosmos-sdk/codec/types" sdk "github.com/cosmos/cosmos-sdk/types" ) @@ -128,14 +127,3 @@ func (qrt *GRPCQueryRouter) SetInterfaceRegistry(interfaceRegistry codectypes.In reflection.NewReflectionServiceServer(interfaceRegistry), ) } - -// RegisterSimulateService registers the simulate service on the gRPC router. -func (qrt *GRPCQueryRouter) RegisterSimulateService( - simulateFn simulate.BaseAppSimulateFn, - interfaceRegistry codectypes.InterfaceRegistry, -) { - simulate.RegisterSimulateServiceServer( - qrt, - simulate.NewSimulateServer(simulateFn, interfaceRegistry), - ) -} diff --git a/client/grpc/simulate/simulate.go b/client/grpc/simulate/simulate.go deleted file mode 100644 index 9eed3e30a167..000000000000 --- a/client/grpc/simulate/simulate.go +++ /dev/null @@ -1,55 +0,0 @@ -package simulate - -import ( - "context" - - "google.golang.org/grpc/codes" - "google.golang.org/grpc/status" - - codectypes "github.com/cosmos/cosmos-sdk/codec/types" - sdk "github.com/cosmos/cosmos-sdk/types" -) - -// BaseAppSimulateFn is the signature of the Baseapp#Simulate function. -type BaseAppSimulateFn func(txBytes []byte) (sdk.GasInfo, *sdk.Result, error) - -type simulateServer struct { - simulate BaseAppSimulateFn - interfaceRegistry codectypes.InterfaceRegistry -} - -// NewSimulateServer creates a new SimulateServer. -func NewSimulateServer(simulate BaseAppSimulateFn, interfaceRegistry codectypes.InterfaceRegistry) SimulateServiceServer { - return simulateServer{ - simulate: simulate, - interfaceRegistry: interfaceRegistry, - } -} - -var _ SimulateServiceServer = simulateServer{} - -// Simulate implements the SimulateService.Simulate RPC method. -func (s simulateServer) Simulate(ctx context.Context, req *SimulateRequest) (*SimulateResponse, error) { - if req.Tx == nil { - return nil, status.Error(codes.InvalidArgument, "invalid empty tx") - } - - err := req.Tx.UnpackInterfaces(s.interfaceRegistry) - if err != nil { - return nil, err - } - txBytes, err := req.Tx.Marshal() - if err != nil { - return nil, err - } - - gasInfo, result, err := s.simulate(txBytes) - if err != nil { - return nil, err - } - - return &SimulateResponse{ - GasInfo: &gasInfo, - Result: result, - }, nil -} diff --git a/client/grpc/simulate/simulate.pb.go b/client/grpc/simulate/simulate.pb.go deleted file mode 100644 index 8fe707913e00..000000000000 --- a/client/grpc/simulate/simulate.pb.go +++ /dev/null @@ -1,679 +0,0 @@ -// Code generated by protoc-gen-gogo. DO NOT EDIT. -// source: cosmos/base/simulate/v1beta1/simulate.proto - -package simulate - -import ( - context "context" - fmt "fmt" - types "github.com/cosmos/cosmos-sdk/types" - tx "github.com/cosmos/cosmos-sdk/types/tx" - grpc1 "github.com/gogo/protobuf/grpc" - proto "github.com/gogo/protobuf/proto" - _ "google.golang.org/genproto/googleapis/api/annotations" - grpc "google.golang.org/grpc" - codes "google.golang.org/grpc/codes" - status "google.golang.org/grpc/status" - io "io" - math "math" - math_bits "math/bits" -) - -// Reference imports to suppress errors if they are not otherwise used. -var _ = proto.Marshal -var _ = fmt.Errorf -var _ = math.Inf - -// This is a compile-time assertion to ensure that this generated file -// is compatible with the proto package it is being compiled against. -// A compilation error at this line likely means your copy of the -// proto package needs to be updated. -const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package - -// SimulateRequest is the request type for the SimulateServiceService.Simulate -// RPC method. -type SimulateRequest struct { - // tx is the transaction to simulate. - Tx *tx.Tx `protobuf:"bytes,1,opt,name=tx,proto3" json:"tx,omitempty"` -} - -func (m *SimulateRequest) Reset() { *m = SimulateRequest{} } -func (m *SimulateRequest) String() string { return proto.CompactTextString(m) } -func (*SimulateRequest) ProtoMessage() {} -func (*SimulateRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_503c836d80bb2d47, []int{0} -} -func (m *SimulateRequest) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *SimulateRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - if deterministic { - return xxx_messageInfo_SimulateRequest.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 *SimulateRequest) XXX_Merge(src proto.Message) { - xxx_messageInfo_SimulateRequest.Merge(m, src) -} -func (m *SimulateRequest) XXX_Size() int { - return m.Size() -} -func (m *SimulateRequest) XXX_DiscardUnknown() { - xxx_messageInfo_SimulateRequest.DiscardUnknown(m) -} - -var xxx_messageInfo_SimulateRequest proto.InternalMessageInfo - -func (m *SimulateRequest) GetTx() *tx.Tx { - if m != nil { - return m.Tx - } - return nil -} - -// SimulateResponse is the response type for the -// SimulateServiceService.SimulateRPC method. -type SimulateResponse struct { - // gas_info is the information about gas used in the simulation. - GasInfo *types.GasInfo `protobuf:"bytes,1,opt,name=gas_info,json=gasInfo,proto3" json:"gas_info,omitempty"` - // result is the result of the simulation. - Result *types.Result `protobuf:"bytes,2,opt,name=result,proto3" json:"result,omitempty"` -} - -func (m *SimulateResponse) Reset() { *m = SimulateResponse{} } -func (m *SimulateResponse) String() string { return proto.CompactTextString(m) } -func (*SimulateResponse) ProtoMessage() {} -func (*SimulateResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_503c836d80bb2d47, []int{1} -} -func (m *SimulateResponse) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *SimulateResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - if deterministic { - return xxx_messageInfo_SimulateResponse.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 *SimulateResponse) XXX_Merge(src proto.Message) { - xxx_messageInfo_SimulateResponse.Merge(m, src) -} -func (m *SimulateResponse) XXX_Size() int { - return m.Size() -} -func (m *SimulateResponse) XXX_DiscardUnknown() { - xxx_messageInfo_SimulateResponse.DiscardUnknown(m) -} - -var xxx_messageInfo_SimulateResponse proto.InternalMessageInfo - -func (m *SimulateResponse) GetGasInfo() *types.GasInfo { - if m != nil { - return m.GasInfo - } - return nil -} - -func (m *SimulateResponse) GetResult() *types.Result { - if m != nil { - return m.Result - } - return nil -} - -func init() { - proto.RegisterType((*SimulateRequest)(nil), "cosmos.base.simulate.v1beta1.SimulateRequest") - proto.RegisterType((*SimulateResponse)(nil), "cosmos.base.simulate.v1beta1.SimulateResponse") -} - -func init() { - proto.RegisterFile("cosmos/base/simulate/v1beta1/simulate.proto", fileDescriptor_503c836d80bb2d47) -} - -var fileDescriptor_503c836d80bb2d47 = []byte{ - // 351 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x91, 0xbf, 0x4b, 0xf3, 0x40, - 0x18, 0xc7, 0x7b, 0x19, 0xfa, 0x96, 0x7b, 0x87, 0xf7, 0x25, 0x20, 0x94, 0x50, 0x42, 0x8d, 0x28, - 0x05, 0xe9, 0x1d, 0xad, 0x4b, 0x07, 0x27, 0x17, 0x11, 0xb7, 0xd4, 0xc9, 0x45, 0x2e, 0xf1, 0x1a, - 0x0f, 0xd3, 0xbb, 0x98, 0x7b, 0x52, 0x32, 0x3b, 0x3a, 0x09, 0x4e, 0xfe, 0x11, 0xfe, 0x1f, 0x8e, - 0x05, 0x17, 0x47, 0x69, 0xfd, 0x43, 0xa4, 0xc9, 0x25, 0x2d, 0x82, 0xd2, 0x29, 0xb9, 0xe7, 0xf9, - 0x7c, 0xbf, 0xcf, 0x2f, 0x7c, 0x18, 0x2a, 0x3d, 0x55, 0x9a, 0x06, 0x4c, 0x73, 0xaa, 0xc5, 0x34, - 0x8b, 0x19, 0x70, 0x3a, 0x1b, 0x04, 0x1c, 0xd8, 0xa0, 0x0e, 0x90, 0x24, 0x55, 0xa0, 0xec, 0x4e, - 0x09, 0x93, 0x15, 0x4c, 0xea, 0x9c, 0x81, 0x9d, 0x4e, 0xa4, 0x54, 0x14, 0x73, 0xca, 0x12, 0x41, - 0x99, 0x94, 0x0a, 0x18, 0x08, 0x25, 0x75, 0xa9, 0x75, 0xf6, 0x36, 0x0b, 0xb1, 0x20, 0x14, 0x75, - 0x91, 0xd5, 0xc3, 0x40, 0x8e, 0x81, 0x20, 0xaf, 0xb3, 0x90, 0x97, 0x39, 0x6f, 0x84, 0xff, 0x8d, - 0x4d, 0x49, 0x9f, 0xdf, 0x65, 0x5c, 0x83, 0xbd, 0x8f, 0x2d, 0xc8, 0xdb, 0xa8, 0x8b, 0x7a, 0x7f, - 0x87, 0x3b, 0xc4, 0x34, 0x07, 0x79, 0xd5, 0x11, 0xb9, 0xc8, 0x7d, 0x0b, 0x72, 0xef, 0x01, 0xe1, - 0xff, 0x6b, 0xa9, 0x4e, 0x94, 0xd4, 0xdc, 0x3e, 0xc6, 0xad, 0x88, 0xe9, 0x2b, 0x21, 0x27, 0xca, - 0x38, 0xec, 0x92, 0xcd, 0xf1, 0x8a, 0xae, 0x2a, 0xa3, 0x53, 0xa6, 0xcf, 0xe4, 0x44, 0xf9, 0x7f, - 0xa2, 0xf2, 0xc7, 0x1e, 0xe1, 0x66, 0xca, 0x75, 0x16, 0x43, 0xdb, 0x2a, 0xb4, 0xdd, 0x9f, 0xb5, - 0x7e, 0xc1, 0xf9, 0x86, 0x1f, 0xbe, 0xa0, 0xf5, 0x1c, 0x63, 0x9e, 0xce, 0x44, 0xc8, 0xed, 0x67, - 0x84, 0x5b, 0x55, 0xcc, 0xee, 0x93, 0xdf, 0xb6, 0x4c, 0xbe, 0xed, 0xc0, 0x21, 0xdb, 0xe2, 0xe5, - 0xdc, 0x1e, 0xb9, 0x7f, 0xfb, 0x7c, 0xb2, 0x7a, 0xde, 0x01, 0xdd, 0xea, 0xf2, 0x27, 0xe7, 0xaf, - 0x0b, 0x17, 0xcd, 0x17, 0x2e, 0xfa, 0x58, 0xb8, 0xe8, 0x71, 0xe9, 0x36, 0xe6, 0x4b, 0xb7, 0xf1, - 0xbe, 0x74, 0x1b, 0x97, 0x83, 0x48, 0xc0, 0x4d, 0x16, 0x90, 0x50, 0x4d, 0x2b, 0xaf, 0xf2, 0xd3, - 0xd7, 0xd7, 0xb7, 0x34, 0x8c, 0x05, 0x97, 0x40, 0xa3, 0x34, 0x09, 0x6b, 0xb3, 0xa0, 0x59, 0x9c, - 0xf2, 0xe8, 0x2b, 0x00, 0x00, 0xff, 0xff, 0x7d, 0x16, 0xed, 0x90, 0x76, 0x02, 0x00, 0x00, -} - -// Reference imports to suppress errors if they are not otherwise used. -var _ context.Context -var _ grpc.ClientConn - -// This is a compile-time assertion to ensure that this generated file -// is compatible with the grpc package it is being compiled against. -const _ = grpc.SupportPackageIsVersion4 - -// SimulateServiceClient is the client API for SimulateService service. -// -// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. -type SimulateServiceClient interface { - // Simulate simulates executing a transaction for estimating gas usage. - Simulate(ctx context.Context, in *SimulateRequest, opts ...grpc.CallOption) (*SimulateResponse, error) -} - -type simulateServiceClient struct { - cc grpc1.ClientConn -} - -func NewSimulateServiceClient(cc grpc1.ClientConn) SimulateServiceClient { - return &simulateServiceClient{cc} -} - -func (c *simulateServiceClient) Simulate(ctx context.Context, in *SimulateRequest, opts ...grpc.CallOption) (*SimulateResponse, error) { - out := new(SimulateResponse) - err := c.cc.Invoke(ctx, "/cosmos.base.simulate.v1beta1.SimulateService/Simulate", in, out, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -// SimulateServiceServer is the server API for SimulateService service. -type SimulateServiceServer interface { - // Simulate simulates executing a transaction for estimating gas usage. - Simulate(context.Context, *SimulateRequest) (*SimulateResponse, error) -} - -// UnimplementedSimulateServiceServer can be embedded to have forward compatible implementations. -type UnimplementedSimulateServiceServer struct { -} - -func (*UnimplementedSimulateServiceServer) Simulate(ctx context.Context, req *SimulateRequest) (*SimulateResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method Simulate not implemented") -} - -func RegisterSimulateServiceServer(s grpc1.Server, srv SimulateServiceServer) { - s.RegisterService(&_SimulateService_serviceDesc, srv) -} - -func _SimulateService_Simulate_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(SimulateRequest) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(SimulateServiceServer).Simulate(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: "/cosmos.base.simulate.v1beta1.SimulateService/Simulate", - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(SimulateServiceServer).Simulate(ctx, req.(*SimulateRequest)) - } - return interceptor(ctx, in, info, handler) -} - -var _SimulateService_serviceDesc = grpc.ServiceDesc{ - ServiceName: "cosmos.base.simulate.v1beta1.SimulateService", - HandlerType: (*SimulateServiceServer)(nil), - Methods: []grpc.MethodDesc{ - { - MethodName: "Simulate", - Handler: _SimulateService_Simulate_Handler, - }, - }, - Streams: []grpc.StreamDesc{}, - Metadata: "cosmos/base/simulate/v1beta1/simulate.proto", -} - -func (m *SimulateRequest) 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 *SimulateRequest) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *SimulateRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - if m.Tx != nil { - { - size, err := m.Tx.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintSimulate(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0xa - } - return len(dAtA) - i, nil -} - -func (m *SimulateResponse) 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 *SimulateResponse) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *SimulateResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - if m.Result != nil { - { - size, err := m.Result.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintSimulate(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x12 - } - if m.GasInfo != nil { - { - size, err := m.GasInfo.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintSimulate(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0xa - } - return len(dAtA) - i, nil -} - -func encodeVarintSimulate(dAtA []byte, offset int, v uint64) int { - offset -= sovSimulate(v) - base := offset - for v >= 1<<7 { - dAtA[offset] = uint8(v&0x7f | 0x80) - v >>= 7 - offset++ - } - dAtA[offset] = uint8(v) - return base -} -func (m *SimulateRequest) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - if m.Tx != nil { - l = m.Tx.Size() - n += 1 + l + sovSimulate(uint64(l)) - } - return n -} - -func (m *SimulateResponse) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - if m.GasInfo != nil { - l = m.GasInfo.Size() - n += 1 + l + sovSimulate(uint64(l)) - } - if m.Result != nil { - l = m.Result.Size() - n += 1 + l + sovSimulate(uint64(l)) - } - return n -} - -func sovSimulate(x uint64) (n int) { - return (math_bits.Len64(x|1) + 6) / 7 -} -func sozSimulate(x uint64) (n int) { - return sovSimulate(uint64((x << 1) ^ uint64((int64(x) >> 63)))) -} -func (m *SimulateRequest) 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 ErrIntOverflowSimulate - } - 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: SimulateRequest: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: SimulateRequest: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Tx", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowSimulate - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthSimulate - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthSimulate - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.Tx == nil { - m.Tx = &tx.Tx{} - } - if err := m.Tx.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipSimulate(dAtA[iNdEx:]) - if err != nil { - return err - } - if skippy < 0 { - return ErrInvalidLengthSimulate - } - if (iNdEx + skippy) < 0 { - return ErrInvalidLengthSimulate - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *SimulateResponse) 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 ErrIntOverflowSimulate - } - 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: SimulateResponse: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: SimulateResponse: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field GasInfo", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowSimulate - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthSimulate - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthSimulate - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.GasInfo == nil { - m.GasInfo = &types.GasInfo{} - } - if err := m.GasInfo.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Result", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowSimulate - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthSimulate - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthSimulate - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.Result == nil { - m.Result = &types.Result{} - } - if err := m.Result.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipSimulate(dAtA[iNdEx:]) - if err != nil { - return err - } - if skippy < 0 { - return ErrInvalidLengthSimulate - } - if (iNdEx + skippy) < 0 { - return ErrInvalidLengthSimulate - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func skipSimulate(dAtA []byte) (n int, err error) { - l := len(dAtA) - iNdEx := 0 - depth := 0 - for iNdEx < l { - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return 0, ErrIntOverflowSimulate - } - if iNdEx >= l { - return 0, io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - wireType := int(wire & 0x7) - switch wireType { - case 0: - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return 0, ErrIntOverflowSimulate - } - if iNdEx >= l { - return 0, io.ErrUnexpectedEOF - } - iNdEx++ - if dAtA[iNdEx-1] < 0x80 { - break - } - } - case 1: - iNdEx += 8 - case 2: - var length int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return 0, ErrIntOverflowSimulate - } - if iNdEx >= l { - return 0, io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - length |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - if length < 0 { - return 0, ErrInvalidLengthSimulate - } - iNdEx += length - case 3: - depth++ - case 4: - if depth == 0 { - return 0, ErrUnexpectedEndOfGroupSimulate - } - depth-- - case 5: - iNdEx += 4 - default: - return 0, fmt.Errorf("proto: illegal wireType %d", wireType) - } - if iNdEx < 0 { - return 0, ErrInvalidLengthSimulate - } - if depth == 0 { - return iNdEx, nil - } - } - return 0, io.ErrUnexpectedEOF -} - -var ( - ErrInvalidLengthSimulate = fmt.Errorf("proto: negative length found during unmarshaling") - ErrIntOverflowSimulate = fmt.Errorf("proto: integer overflow") - ErrUnexpectedEndOfGroupSimulate = fmt.Errorf("proto: unexpected end of group") -) diff --git a/client/grpc/simulate/simulate.pb.gw.go b/client/grpc/simulate/simulate.pb.gw.go deleted file mode 100644 index 78cb85437c22..000000000000 --- a/client/grpc/simulate/simulate.pb.gw.go +++ /dev/null @@ -1,166 +0,0 @@ -// Code generated by protoc-gen-grpc-gateway. DO NOT EDIT. -// source: cosmos/base/simulate/v1beta1/simulate.proto - -/* -Package simulate is a reverse proxy. - -It translates gRPC into RESTful JSON APIs. -*/ -package simulate - -import ( - "context" - "io" - "net/http" - - "github.com/golang/protobuf/descriptor" - "github.com/golang/protobuf/proto" - "github.com/grpc-ecosystem/grpc-gateway/runtime" - "github.com/grpc-ecosystem/grpc-gateway/utilities" - "google.golang.org/grpc" - "google.golang.org/grpc/codes" - "google.golang.org/grpc/grpclog" - "google.golang.org/grpc/status" -) - -// Suppress "imported and not used" errors -var _ codes.Code -var _ io.Reader -var _ status.Status -var _ = runtime.String -var _ = utilities.NewDoubleArray -var _ = descriptor.ForMessage - -var ( - filter_SimulateService_Simulate_0 = &utilities.DoubleArray{Encoding: map[string]int{}, Base: []int(nil), Check: []int(nil)} -) - -func request_SimulateService_Simulate_0(ctx context.Context, marshaler runtime.Marshaler, client SimulateServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { - var protoReq SimulateRequest - var metadata runtime.ServerMetadata - - if err := req.ParseForm(); err != nil { - return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) - } - if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_SimulateService_Simulate_0); err != nil { - return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) - } - - msg, err := client.Simulate(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) - return msg, metadata, err - -} - -func local_request_SimulateService_Simulate_0(ctx context.Context, marshaler runtime.Marshaler, server SimulateServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { - var protoReq SimulateRequest - var metadata runtime.ServerMetadata - - if err := req.ParseForm(); err != nil { - return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) - } - if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_SimulateService_Simulate_0); err != nil { - return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) - } - - msg, err := server.Simulate(ctx, &protoReq) - return msg, metadata, err - -} - -// RegisterSimulateServiceHandlerServer registers the http handlers for service SimulateService to "mux". -// UnaryRPC :call SimulateServiceServer directly. -// StreamingRPC :currently unsupported pending https://github.com/grpc/grpc-go/issues/906. -// Note that using this registration option will cause many gRPC library features (such as grpc.SendHeader, etc) to stop working. Consider using RegisterSimulateServiceHandlerFromEndpoint instead. -func RegisterSimulateServiceHandlerServer(ctx context.Context, mux *runtime.ServeMux, server SimulateServiceServer) error { - - mux.Handle("POST", pattern_SimulateService_Simulate_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { - ctx, cancel := context.WithCancel(req.Context()) - defer cancel() - inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) - rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req) - if err != nil { - runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) - return - } - resp, md, err := local_request_SimulateService_Simulate_0(rctx, inboundMarshaler, server, req, pathParams) - ctx = runtime.NewServerMetadataContext(ctx, md) - if err != nil { - runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) - return - } - - forward_SimulateService_Simulate_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) - - }) - - return nil -} - -// RegisterSimulateServiceHandlerFromEndpoint is same as RegisterSimulateServiceHandler but -// automatically dials to "endpoint" and closes the connection when "ctx" gets done. -func RegisterSimulateServiceHandlerFromEndpoint(ctx context.Context, mux *runtime.ServeMux, endpoint string, opts []grpc.DialOption) (err error) { - conn, err := grpc.Dial(endpoint, opts...) - if err != nil { - return err - } - defer func() { - if err != nil { - if cerr := conn.Close(); cerr != nil { - grpclog.Infof("Failed to close conn to %s: %v", endpoint, cerr) - } - return - } - go func() { - <-ctx.Done() - if cerr := conn.Close(); cerr != nil { - grpclog.Infof("Failed to close conn to %s: %v", endpoint, cerr) - } - }() - }() - - return RegisterSimulateServiceHandler(ctx, mux, conn) -} - -// RegisterSimulateServiceHandler registers the http handlers for service SimulateService to "mux". -// The handlers forward requests to the grpc endpoint over "conn". -func RegisterSimulateServiceHandler(ctx context.Context, mux *runtime.ServeMux, conn *grpc.ClientConn) error { - return RegisterSimulateServiceHandlerClient(ctx, mux, NewSimulateServiceClient(conn)) -} - -// RegisterSimulateServiceHandlerClient registers the http handlers for service SimulateService -// to "mux". The handlers forward requests to the grpc endpoint over the given implementation of "SimulateServiceClient". -// Note: the gRPC framework executes interceptors within the gRPC handler. If the passed in "SimulateServiceClient" -// doesn't go through the normal gRPC flow (creating a gRPC client etc.) then it will be up to the passed in -// "SimulateServiceClient" to call the correct interceptors. -func RegisterSimulateServiceHandlerClient(ctx context.Context, mux *runtime.ServeMux, client SimulateServiceClient) error { - - mux.Handle("POST", pattern_SimulateService_Simulate_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { - ctx, cancel := context.WithCancel(req.Context()) - defer cancel() - inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) - rctx, err := runtime.AnnotateContext(ctx, mux, req) - if err != nil { - runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) - return - } - resp, md, err := request_SimulateService_Simulate_0(rctx, inboundMarshaler, client, req, pathParams) - ctx = runtime.NewServerMetadataContext(ctx, md) - if err != nil { - runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) - return - } - - forward_SimulateService_Simulate_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) - - }) - - return nil -} - -var ( - pattern_SimulateService_Simulate_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 2, 2}, []string{"cosmos", "base", "simulate", "v1beta1"}, "", runtime.AssumeColonVerbOpt(true))) -) - -var ( - forward_SimulateService_Simulate_0 = runtime.ForwardResponseMessage -) diff --git a/client/grpc/simulate/simulate_test.go b/client/grpc/simulate/simulate_test.go deleted file mode 100644 index 11b58168a923..000000000000 --- a/client/grpc/simulate/simulate_test.go +++ /dev/null @@ -1,119 +0,0 @@ -package simulate_test - -import ( - "context" - "testing" - - "github.com/stretchr/testify/suite" - tmproto "github.com/tendermint/tendermint/proto/tendermint/types" - - "github.com/cosmos/cosmos-sdk/baseapp" - "github.com/cosmos/cosmos-sdk/client" - "github.com/cosmos/cosmos-sdk/client/grpc/simulate" - "github.com/cosmos/cosmos-sdk/client/tx" - codectypes "github.com/cosmos/cosmos-sdk/codec/types" - "github.com/cosmos/cosmos-sdk/simapp" - "github.com/cosmos/cosmos-sdk/testutil/testdata" - sdk "github.com/cosmos/cosmos-sdk/types" - txtypes "github.com/cosmos/cosmos-sdk/types/tx" - "github.com/cosmos/cosmos-sdk/types/tx/signing" - authsigning "github.com/cosmos/cosmos-sdk/x/auth/signing" - authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" - banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" -) - -type IntegrationTestSuite struct { - suite.Suite - - app *simapp.SimApp - clientCtx client.Context - queryClient simulate.SimulateServiceClient - sdkCtx sdk.Context -} - -func (s *IntegrationTestSuite) SetupSuite() { - app := simapp.Setup(true) - sdkCtx := app.BaseApp.NewContext(true, tmproto.Header{}) - - app.AccountKeeper.SetParams(sdkCtx, authtypes.DefaultParams()) - app.BankKeeper.SetParams(sdkCtx, banktypes.DefaultParams()) - - // Set up TxConfig. - encodingConfig := simapp.MakeTestEncodingConfig() - clientCtx := client.Context{}.WithTxConfig(encodingConfig.TxConfig) - - // Create new simulation server. - srv := simulate.NewSimulateServer(app.BaseApp.Simulate, encodingConfig.InterfaceRegistry) - - queryHelper := baseapp.NewQueryServerTestHelper(sdkCtx, app.InterfaceRegistry()) - simulate.RegisterSimulateServiceServer(queryHelper, srv) - queryClient := simulate.NewSimulateServiceClient(queryHelper) - - s.app = app - s.clientCtx = clientCtx - s.queryClient = queryClient - s.sdkCtx = sdkCtx -} - -func (s IntegrationTestSuite) TestSimulateService() { - // Create an account with some funds. - priv1, _, addr1 := testdata.KeyTestPubAddr() - acc1 := s.app.AccountKeeper.NewAccountWithAddress(s.sdkCtx, addr1) - err := acc1.SetAccountNumber(0) - s.Require().NoError(err) - s.app.AccountKeeper.SetAccount(s.sdkCtx, acc1) - s.app.BankKeeper.SetBalances(s.sdkCtx, addr1, sdk.Coins{ - sdk.NewInt64Coin("atom", 10000000), - }) - - // Create a test x/bank MsgSend. - coins := sdk.NewCoins(sdk.NewInt64Coin("atom", 10)) - _, _, addr2 := testdata.KeyTestPubAddr() - msg := banktypes.NewMsgSend(addr1, addr2, coins) - feeAmount := testdata.NewTestFeeAmount() - gasLimit := testdata.NewTestGasLimit() - memo := "foo" - accSeq, accNum := uint64(0), uint64(0) - - // Create a txBuilder. - txBuilder := s.clientCtx.TxConfig.NewTxBuilder() - txBuilder.SetMsgs(msg) - txBuilder.SetMemo(memo) - txBuilder.SetFeeAmount(feeAmount) - txBuilder.SetGasLimit(gasLimit) - // 1st round: set empty signature - sigV2 := signing.SignatureV2{ - PubKey: priv1.PubKey(), - Data: &signing.SingleSignatureData{ - SignMode: s.clientCtx.TxConfig.SignModeHandler().DefaultMode(), - Signature: nil, - }, - } - txBuilder.SetSignatures(sigV2) - // 2nd round: actually sign - sigV2, err = tx.SignWithPrivKey( - s.clientCtx.TxConfig.SignModeHandler().DefaultMode(), - authsigning.SignerData{ChainID: s.sdkCtx.ChainID(), AccountNumber: accNum, Sequence: accSeq}, - txBuilder, priv1, s.clientCtx.TxConfig, accSeq, - ) - txBuilder.SetSignatures(sigV2) - - any, ok := txBuilder.(codectypes.IntoAny) - s.Require().True(ok) - cached := any.AsAny().GetCachedValue() - txTx, ok := cached.(*txtypes.Tx) - s.Require().True(ok) - res, err := s.queryClient.Simulate( - context.Background(), - &simulate.SimulateRequest{Tx: txTx}, - ) - s.Require().NoError(err) - - // Check the result and gas used are correct. - s.Require().Equal(len(res.GetResult().GetEvents()), 4) // 1 transfer, 3 messages. - s.Require().True(res.GetGasInfo().GetGasUsed() > 0) // Gas used sometimes change, just check it's not empty. -} - -func TestSimulateTestSuite(t *testing.T) { - suite.Run(t, new(IntegrationTestSuite)) -} diff --git a/client/tx/tx.go b/client/tx/tx.go index 43f2235b1b9b..fb0e71280501 100644 --- a/client/tx/tx.go +++ b/client/tx/tx.go @@ -12,7 +12,6 @@ import ( "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/flags" - sim "github.com/cosmos/cosmos-sdk/client/grpc/simulate" "github.com/cosmos/cosmos-sdk/client/input" codectypes "github.com/cosmos/cosmos-sdk/codec/types" "github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1" @@ -279,7 +278,7 @@ func BuildSimTx(txf Factory, msgs ...sdk.Msg) ([]byte, error) { return nil, fmt.Errorf("cannot simulate amino tx") } - simReq := sim.SimulateRequest{Tx: protoTx} + simReq := tx.SimulateRequest{Tx: protoTx} return simReq.Marshal() } @@ -288,21 +287,23 @@ func BuildSimTx(txf Factory, msgs ...sdk.Msg) ([]byte, error) { // simulation response obtained by the query and the adjusted gas amount. func CalculateGas( queryFunc func(string, []byte) ([]byte, int64, error), txf Factory, msgs ...sdk.Msg, -) (sim.SimulateResponse, uint64, error) { +) (tx.SimulateResponse, uint64, error) { txBytes, err := BuildSimTx(txf, msgs...) if err != nil { - return sim.SimulateResponse{}, 0, err + return tx.SimulateResponse{}, 0, err } - bz, _, err := queryFunc("/cosmos.base.simulate.v1beta1.SimulateService/Simulate", txBytes) + // TODO This should use the generated tx service Client. + // https://github.com/cosmos/cosmos-sdk/issues/7726 + bz, _, err := queryFunc("/cosmos.tx.v1beta1.Service/Simulate", txBytes) if err != nil { - return sim.SimulateResponse{}, 0, err + return tx.SimulateResponse{}, 0, err } - var simRes sim.SimulateResponse + var simRes tx.SimulateResponse if err := simRes.Unmarshal(bz); err != nil { - return sim.SimulateResponse{}, 0, err + return tx.SimulateResponse{}, 0, err } return simRes, uint64(txf.GasAdjustment() * float64(simRes.GasInfo.GasUsed)), nil diff --git a/client/tx/tx_test.go b/client/tx/tx_test.go index da4db5fc8bff..3325e738d553 100644 --- a/client/tx/tx_test.go +++ b/client/tx/tx_test.go @@ -7,12 +7,12 @@ import ( "github.com/stretchr/testify/require" "github.com/cosmos/cosmos-sdk/client" - "github.com/cosmos/cosmos-sdk/client/grpc/simulate" "github.com/cosmos/cosmos-sdk/client/tx" "github.com/cosmos/cosmos-sdk/crypto/hd" "github.com/cosmos/cosmos-sdk/crypto/keyring" "github.com/cosmos/cosmos-sdk/simapp" sdk "github.com/cosmos/cosmos-sdk/types" + txtypes "github.com/cosmos/cosmos-sdk/types/tx" "github.com/cosmos/cosmos-sdk/x/auth/signing" banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" ) @@ -28,7 +28,7 @@ func TestCalculateGas(t *testing.T) { if wantErr { return nil, 0, errors.New("query failed") } - simRes := &simulate.SimulateResponse{ + simRes := &txtypes.SimulateResponse{ GasInfo: &sdk.GasInfo{GasUsed: gasUsed, GasWanted: gasUsed}, Result: &sdk.Result{Data: []byte("tx data"), Log: "log"}, } diff --git a/proto/cosmos/base/simulate/v1beta1/simulate.proto b/proto/cosmos/base/simulate/v1beta1/simulate.proto deleted file mode 100644 index e7e678d99cdb..000000000000 --- a/proto/cosmos/base/simulate/v1beta1/simulate.proto +++ /dev/null @@ -1,33 +0,0 @@ -syntax = "proto3"; -package cosmos.base.simulate.v1beta1; - -import "google/api/annotations.proto"; -import "cosmos/base/abci/v1beta1/abci.proto"; -import "cosmos/tx/v1beta1/tx.proto"; - -option go_package = "github.com/cosmos/cosmos-sdk/client/grpc/simulate"; - -// SimulateService defines a gRPC service for simulating transactions. -// It may also support querying and broadcasting in the future. -service SimulateService { - // Simulate simulates executing a transaction for estimating gas usage. - rpc Simulate(SimulateRequest) returns (SimulateResponse) { - option (google.api.http).post = "/cosmos/base/simulate/v1beta1/simulate"; - } -} - -// SimulateRequest is the request type for the SimulateServiceService.Simulate -// RPC method. -message SimulateRequest { - // tx is the transaction to simulate. - cosmos.tx.v1beta1.Tx tx = 1; -} - -// SimulateResponse is the response type for the -// SimulateServiceService.SimulateRPC method. -message SimulateResponse { - // gas_info is the information about gas used in the simulation. - cosmos.base.abci.v1beta1.GasInfo gas_info = 1; - // result is the result of the simulation. - cosmos.base.abci.v1beta1.Result result = 2; -} diff --git a/proto/cosmos/tx/v1beta1/service.proto b/proto/cosmos/tx/v1beta1/service.proto new file mode 100644 index 000000000000..eb7784001cc8 --- /dev/null +++ b/proto/cosmos/tx/v1beta1/service.proto @@ -0,0 +1,49 @@ +syntax = "proto3"; +package cosmos.tx.v1beta1; + +import "google/api/annotations.proto"; +import "cosmos/base/abci/v1beta1/abci.proto"; +import "cosmos/tx/v1beta1/tx.proto"; + +option go_package = "github.com/cosmos/cosmos-sdk/types/tx"; + +// Service defines a gRPC service for interacting with transactions. +service Service { + // Simulate simulates executing a transaction for estimating gas usage. + rpc Simulate(SimulateRequest) returns (SimulateResponse) { + option (google.api.http).post = "/cosmos/tx/v1beta1/simulate"; + } + // GetTx fetches a tx by hash. + rpc GetTx(GetTxRequest) returns (GetTxResponse) { + option (google.api.http).get = "/cosmos/tx/v1beta1/tx/{hash}"; + } +} + +// SimulateRequest is the request type for the Service.Simulate +// RPC method. +message SimulateRequest { + // tx is the transaction to simulate. + cosmos.tx.v1beta1.Tx tx = 1; +} + +// SimulateResponse is the response type for the +// Service.SimulateRPC method. +message SimulateResponse { + // gas_info is the information about gas used in the simulation. + cosmos.base.abci.v1beta1.GasInfo gas_info = 1; + // result is the result of the simulation. + cosmos.base.abci.v1beta1.Result result = 2; +} + +// GetTx is the request type for the Service.GetTx +// RPC method. +message GetTxRequest { + // hash is the tx hash to query, encoded as a hex string. + string hash = 1; +} + +// GetTxResponse is the response type for the Service.GetTx method. +message GetTxResponse { + // tx is the queried transaction. + cosmos.tx.v1beta1.Tx tx = 1; +} diff --git a/server/start.go b/server/start.go index ca39a7606e64..6e014de75080 100644 --- a/server/start.go +++ b/server/start.go @@ -231,6 +231,9 @@ func startInProcess(ctx *Context, clientCtx client.Context, appCreator types.App return err } + // Add the tx service to the gRPC router. + app.RegisterTxService(clientCtx) + var apiSrv *api.Server config := config.GetConfig(ctx.Viper) diff --git a/server/types/app.go b/server/types/app.go index 9dfc565ee345..f036f6ff093c 100644 --- a/server/types/app.go +++ b/server/types/app.go @@ -10,6 +10,7 @@ import ( tmtypes "github.com/tendermint/tendermint/types" dbm "github.com/tendermint/tm-db" + "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/server/api" "github.com/cosmos/cosmos-sdk/server/config" ) @@ -37,6 +38,10 @@ type ( // RegisterGRPCServer registers gRPC services directly with the gRPC // server. RegisterGRPCServer(grpc.Server) + + // RegisterTxService registers the gRPC Query service for tx (such as tx + // simulation, fetching txs by hash...). + RegisterTxService(clientCtx client.Context) } // AppCreator is a function that allows us to lazily initialize an diff --git a/simapp/app.go b/simapp/app.go index 0d1d226d857f..3f11216af3fa 100644 --- a/simapp/app.go +++ b/simapp/app.go @@ -22,6 +22,7 @@ import ( "github.com/cosmos/cosmos-sdk/codec/types" "github.com/cosmos/cosmos-sdk/server/api" "github.com/cosmos/cosmos-sdk/server/config" + servertypes "github.com/cosmos/cosmos-sdk/server/types" simappparams "github.com/cosmos/cosmos-sdk/simapp/params" "github.com/cosmos/cosmos-sdk/testutil/testdata" sdk "github.com/cosmos/cosmos-sdk/types" @@ -32,6 +33,7 @@ import ( authrest "github.com/cosmos/cosmos-sdk/x/auth/client/rest" authkeeper "github.com/cosmos/cosmos-sdk/x/auth/keeper" authsims "github.com/cosmos/cosmos-sdk/x/auth/simulation" + authtx "github.com/cosmos/cosmos-sdk/x/auth/tx" authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" "github.com/cosmos/cosmos-sdk/x/auth/vesting" "github.com/cosmos/cosmos-sdk/x/bank" @@ -134,7 +136,10 @@ var ( } ) -var _ App = (*SimApp)(nil) +var ( + _ App = (*SimApp)(nil) + _ servertypes.Application = (*SimApp)(nil) +) // SimApp extends an ABCI application, but with most of its parameters exported. // They are exported for convenience in creating helper functions, as object @@ -204,7 +209,6 @@ func NewSimApp( bApp.SetCommitMultiStoreTracer(traceStore) bApp.SetAppVersion(version.Version) bApp.SetInterfaceRegistry(interfaceRegistry) - bApp.GRPCQueryRouter().RegisterSimulateService(bApp.Simulate, interfaceRegistry) keys := sdk.NewKVStoreKeys( authtypes.StoreKey, banktypes.StoreKey, stakingtypes.StoreKey, @@ -544,10 +548,14 @@ func (app *SimApp) SimulationManager() *module.SimulationManager { func (app *SimApp) RegisterAPIRoutes(apiSvr *api.Server, apiConfig config.APIConfig) { clientCtx := apiSvr.ClientCtx rpc.RegisterRoutes(clientCtx, apiSvr.Router) + // Register legacy tx routes. authrest.RegisterTxRoutes(clientCtx, apiSvr.Router) + // Register new tx routes from grpc-gateway. + authtx.RegisterGRPCGatewayRoutes(clientCtx, apiSvr.GRPCRouter) + // Register legacy and grpc-gateway routes for all modules. ModuleBasics.RegisterRESTRoutes(clientCtx, apiSvr.Router) - ModuleBasics.RegisterGRPCGatewayRoutes(apiSvr.ClientCtx, apiSvr.GRPCRouter) + ModuleBasics.RegisterGRPCGatewayRoutes(clientCtx, apiSvr.GRPCRouter) // register swagger API from root so that other applications can override easily if apiConfig.Swagger { @@ -555,6 +563,11 @@ func (app *SimApp) RegisterAPIRoutes(apiSvr *api.Server, apiConfig config.APICon } } +// RegisterTxService implements the Application.RegisterTxService method. +func (app *SimApp) RegisterTxService(clientCtx client.Context) { + authtx.RegisterTxService(app.BaseApp.GRPCQueryRouter(), clientCtx, app.BaseApp.Simulate, app.interfaceRegistry) +} + // RegisterSwaggerAPI registers swagger route with API Server func RegisterSwaggerAPI(ctx client.Context, rtr *mux.Router) { statikFS, err := fs.New() diff --git a/testutil/network/util.go b/testutil/network/util.go index 28a43ea7d599..d85dafd0a15a 100644 --- a/testutil/network/util.go +++ b/testutil/network/util.go @@ -59,10 +59,16 @@ func startInProcess(cfg Config, val *Validator) error { val.RPCClient = local.New(tmNode) } - if val.APIAddress != "" { + // We'll need a RPC client if the validator exposes a gRPC or REST endpoint. + if val.APIAddress != "" || val.AppConfig.GRPC.Enable { val.ClientCtx = val.ClientCtx. WithClient(val.RPCClient) + // Add the tx service in the gRPC router. + app.RegisterTxService(val.ClientCtx) + } + + if val.APIAddress != "" { apiSrv := api.New(val.ClientCtx, logger.With("module", "api-server")) app.RegisterAPIRoutes(apiSrv, val.AppConfig.API) diff --git a/types/tx/service.pb.go b/types/tx/service.pb.go new file mode 100644 index 000000000000..ae691fd6273a --- /dev/null +++ b/types/tx/service.pb.go @@ -0,0 +1,1078 @@ +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: cosmos/tx/v1beta1/service.proto + +package tx + +import ( + context "context" + fmt "fmt" + types "github.com/cosmos/cosmos-sdk/types" + grpc1 "github.com/gogo/protobuf/grpc" + proto "github.com/gogo/protobuf/proto" + _ "google.golang.org/genproto/googleapis/api/annotations" + grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" + io "io" + math "math" + math_bits "math/bits" +) + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package + +// SimulateRequest is the request type for the Service.Simulate +// RPC method. +type SimulateRequest struct { + // tx is the transaction to simulate. + Tx *Tx `protobuf:"bytes,1,opt,name=tx,proto3" json:"tx,omitempty"` +} + +func (m *SimulateRequest) Reset() { *m = SimulateRequest{} } +func (m *SimulateRequest) String() string { return proto.CompactTextString(m) } +func (*SimulateRequest) ProtoMessage() {} +func (*SimulateRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_e0b00a618705eca7, []int{0} +} +func (m *SimulateRequest) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *SimulateRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_SimulateRequest.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 *SimulateRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_SimulateRequest.Merge(m, src) +} +func (m *SimulateRequest) XXX_Size() int { + return m.Size() +} +func (m *SimulateRequest) XXX_DiscardUnknown() { + xxx_messageInfo_SimulateRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_SimulateRequest proto.InternalMessageInfo + +func (m *SimulateRequest) GetTx() *Tx { + if m != nil { + return m.Tx + } + return nil +} + +// SimulateResponse is the response type for the +// Service.SimulateRPC method. +type SimulateResponse struct { + // gas_info is the information about gas used in the simulation. + GasInfo *types.GasInfo `protobuf:"bytes,1,opt,name=gas_info,json=gasInfo,proto3" json:"gas_info,omitempty"` + // result is the result of the simulation. + Result *types.Result `protobuf:"bytes,2,opt,name=result,proto3" json:"result,omitempty"` +} + +func (m *SimulateResponse) Reset() { *m = SimulateResponse{} } +func (m *SimulateResponse) String() string { return proto.CompactTextString(m) } +func (*SimulateResponse) ProtoMessage() {} +func (*SimulateResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_e0b00a618705eca7, []int{1} +} +func (m *SimulateResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *SimulateResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_SimulateResponse.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 *SimulateResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_SimulateResponse.Merge(m, src) +} +func (m *SimulateResponse) XXX_Size() int { + return m.Size() +} +func (m *SimulateResponse) XXX_DiscardUnknown() { + xxx_messageInfo_SimulateResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_SimulateResponse proto.InternalMessageInfo + +func (m *SimulateResponse) GetGasInfo() *types.GasInfo { + if m != nil { + return m.GasInfo + } + return nil +} + +func (m *SimulateResponse) GetResult() *types.Result { + if m != nil { + return m.Result + } + return nil +} + +// GetTx is the request type for the Service.GetTx +// RPC method. +type GetTxRequest struct { + // hash is the tx hash to query, encoded as a hex string. + Hash string `protobuf:"bytes,1,opt,name=hash,proto3" json:"hash,omitempty"` +} + +func (m *GetTxRequest) Reset() { *m = GetTxRequest{} } +func (m *GetTxRequest) String() string { return proto.CompactTextString(m) } +func (*GetTxRequest) ProtoMessage() {} +func (*GetTxRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_e0b00a618705eca7, []int{2} +} +func (m *GetTxRequest) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *GetTxRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_GetTxRequest.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 *GetTxRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_GetTxRequest.Merge(m, src) +} +func (m *GetTxRequest) XXX_Size() int { + return m.Size() +} +func (m *GetTxRequest) XXX_DiscardUnknown() { + xxx_messageInfo_GetTxRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_GetTxRequest proto.InternalMessageInfo + +func (m *GetTxRequest) GetHash() string { + if m != nil { + return m.Hash + } + return "" +} + +// GetTxResponse is the response type for the Service.GetTx method. +type GetTxResponse struct { + // tx is the queried transaction. + Tx *Tx `protobuf:"bytes,1,opt,name=tx,proto3" json:"tx,omitempty"` +} + +func (m *GetTxResponse) Reset() { *m = GetTxResponse{} } +func (m *GetTxResponse) String() string { return proto.CompactTextString(m) } +func (*GetTxResponse) ProtoMessage() {} +func (*GetTxResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_e0b00a618705eca7, []int{3} +} +func (m *GetTxResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *GetTxResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_GetTxResponse.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 *GetTxResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_GetTxResponse.Merge(m, src) +} +func (m *GetTxResponse) XXX_Size() int { + return m.Size() +} +func (m *GetTxResponse) XXX_DiscardUnknown() { + xxx_messageInfo_GetTxResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_GetTxResponse proto.InternalMessageInfo + +func (m *GetTxResponse) GetTx() *Tx { + if m != nil { + return m.Tx + } + return nil +} + +func init() { + proto.RegisterType((*SimulateRequest)(nil), "cosmos.tx.v1beta1.SimulateRequest") + proto.RegisterType((*SimulateResponse)(nil), "cosmos.tx.v1beta1.SimulateResponse") + proto.RegisterType((*GetTxRequest)(nil), "cosmos.tx.v1beta1.GetTxRequest") + proto.RegisterType((*GetTxResponse)(nil), "cosmos.tx.v1beta1.GetTxResponse") +} + +func init() { proto.RegisterFile("cosmos/tx/v1beta1/service.proto", fileDescriptor_e0b00a618705eca7) } + +var fileDescriptor_e0b00a618705eca7 = []byte{ + // 404 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x92, 0x31, 0x6b, 0xdb, 0x40, + 0x1c, 0xc5, 0x2d, 0xd1, 0xda, 0xee, 0xb5, 0xa5, 0xed, 0x41, 0xc1, 0xa8, 0xae, 0xec, 0x9e, 0x6b, + 0xe8, 0x52, 0x1d, 0x76, 0xa1, 0x78, 0x08, 0x04, 0xb2, 0x98, 0xac, 0xb2, 0xa7, 0x2c, 0xe1, 0xa4, + 0x9c, 0x65, 0x11, 0x5b, 0xa7, 0xf8, 0x4e, 0xe6, 0x42, 0xc8, 0x92, 0x31, 0x53, 0x20, 0x5f, 0x2a, + 0xa3, 0x21, 0x4b, 0xc6, 0x60, 0xe7, 0x2b, 0x64, 0x0f, 0x3a, 0x9d, 0x92, 0x10, 0xcb, 0x21, 0x93, + 0x4e, 0xe8, 0xbd, 0xdf, 0xff, 0xbd, 0xd3, 0x1f, 0x34, 0x7c, 0xc6, 0xa7, 0x8c, 0x63, 0x21, 0xf1, + 0xbc, 0xe3, 0x51, 0x41, 0x3a, 0x98, 0xd3, 0xd9, 0x3c, 0xf4, 0xa9, 0x13, 0xcf, 0x98, 0x60, 0xf0, + 0x5b, 0x26, 0x70, 0x84, 0x74, 0xb4, 0xc0, 0xaa, 0x07, 0x8c, 0x05, 0x13, 0x8a, 0x49, 0x1c, 0x62, + 0x12, 0x45, 0x4c, 0x10, 0x11, 0xb2, 0x88, 0x67, 0x06, 0xab, 0xa5, 0x89, 0x1e, 0xe1, 0x14, 0x13, + 0xcf, 0x0f, 0x1f, 0xc1, 0xe9, 0x8b, 0x16, 0x59, 0xeb, 0x63, 0x85, 0xcc, 0xbe, 0xa1, 0x1e, 0xf8, + 0x32, 0x08, 0xa7, 0xc9, 0x84, 0x08, 0xea, 0xd2, 0xa3, 0x84, 0x72, 0x01, 0xdb, 0xc0, 0x14, 0xb2, + 0x66, 0x34, 0x8d, 0x3f, 0x1f, 0xbb, 0xdf, 0x9d, 0xb5, 0x44, 0xce, 0x50, 0xba, 0xa6, 0x90, 0xe8, + 0xdc, 0x00, 0x5f, 0x9f, 0xac, 0x3c, 0x66, 0x11, 0xa7, 0x70, 0x0b, 0x54, 0x03, 0xc2, 0xf7, 0xc3, + 0x68, 0xc4, 0x34, 0xe1, 0x57, 0x4e, 0x48, 0x23, 0x3a, 0x2a, 0x55, 0x0e, 0xea, 0x13, 0xbe, 0x1b, + 0x8d, 0x98, 0x5b, 0x09, 0xb2, 0x03, 0xec, 0x81, 0xf2, 0x8c, 0xf2, 0x64, 0x22, 0x6a, 0xa6, 0xf2, + 0x36, 0x37, 0x7b, 0x5d, 0xa5, 0x73, 0xb5, 0x1e, 0x21, 0xf0, 0xa9, 0x4f, 0xc5, 0x50, 0xe6, 0x1d, + 0x20, 0x78, 0x37, 0x26, 0x7c, 0xac, 0x32, 0x7c, 0x70, 0xd5, 0x19, 0xfd, 0x07, 0x9f, 0xb5, 0x46, + 0x87, 0x7d, 0x5b, 0xd1, 0xee, 0xbd, 0x01, 0x2a, 0x83, 0xec, 0x37, 0x41, 0x09, 0xaa, 0x79, 0x67, + 0x88, 0x0a, 0x2c, 0x2f, 0xee, 0xd2, 0x6a, 0xbd, 0xaa, 0xc9, 0x72, 0xa0, 0xd6, 0xd9, 0xf5, 0xdd, + 0xa5, 0xf9, 0x13, 0xfd, 0xc0, 0x05, 0xfb, 0x91, 0x4f, 0x8b, 0xc1, 0x7b, 0x95, 0x1e, 0x36, 0x0a, + 0x90, 0xcf, 0xbb, 0x5b, 0xcd, 0xcd, 0x02, 0x3d, 0xf0, 0xb7, 0x1a, 0x68, 0xc3, 0x3a, 0x2e, 0xda, + 0x0c, 0x7c, 0x92, 0x5e, 0xd7, 0xe9, 0xce, 0xf6, 0xd5, 0xd2, 0x36, 0x16, 0x4b, 0xdb, 0xb8, 0x5d, + 0xda, 0xc6, 0xc5, 0xca, 0x2e, 0x2d, 0x56, 0x76, 0xe9, 0x66, 0x65, 0x97, 0xf6, 0xda, 0x41, 0x28, + 0xc6, 0x89, 0xe7, 0xf8, 0x6c, 0x9a, 0x13, 0xb2, 0xc7, 0x5f, 0x7e, 0x70, 0x88, 0xc5, 0x71, 0x4c, + 0x53, 0xa4, 0x57, 0x56, 0x2b, 0xf6, 0xef, 0x21, 0x00, 0x00, 0xff, 0xff, 0x0f, 0x4c, 0x40, 0xff, + 0xf7, 0x02, 0x00, 0x00, +} + +// Reference imports to suppress errors if they are not otherwise used. +var _ context.Context +var _ grpc.ClientConn + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +const _ = grpc.SupportPackageIsVersion4 + +// ServiceClient is the client API for Service service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. +type ServiceClient interface { + // Simulate simulates executing a transaction for estimating gas usage. + Simulate(ctx context.Context, in *SimulateRequest, opts ...grpc.CallOption) (*SimulateResponse, error) + // GetTx fetches a tx by hash. + GetTx(ctx context.Context, in *GetTxRequest, opts ...grpc.CallOption) (*GetTxResponse, error) +} + +type serviceClient struct { + cc grpc1.ClientConn +} + +func NewServiceClient(cc grpc1.ClientConn) ServiceClient { + return &serviceClient{cc} +} + +func (c *serviceClient) Simulate(ctx context.Context, in *SimulateRequest, opts ...grpc.CallOption) (*SimulateResponse, error) { + out := new(SimulateResponse) + err := c.cc.Invoke(ctx, "/cosmos.tx.v1beta1.Service/Simulate", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *serviceClient) GetTx(ctx context.Context, in *GetTxRequest, opts ...grpc.CallOption) (*GetTxResponse, error) { + out := new(GetTxResponse) + err := c.cc.Invoke(ctx, "/cosmos.tx.v1beta1.Service/GetTx", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// ServiceServer is the server API for Service service. +type ServiceServer interface { + // Simulate simulates executing a transaction for estimating gas usage. + Simulate(context.Context, *SimulateRequest) (*SimulateResponse, error) + // GetTx fetches a tx by hash. + GetTx(context.Context, *GetTxRequest) (*GetTxResponse, error) +} + +// UnimplementedServiceServer can be embedded to have forward compatible implementations. +type UnimplementedServiceServer struct { +} + +func (*UnimplementedServiceServer) Simulate(ctx context.Context, req *SimulateRequest) (*SimulateResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method Simulate not implemented") +} +func (*UnimplementedServiceServer) GetTx(ctx context.Context, req *GetTxRequest) (*GetTxResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetTx not implemented") +} + +func RegisterServiceServer(s grpc1.Server, srv ServiceServer) { + s.RegisterService(&_Service_serviceDesc, srv) +} + +func _Service_Simulate_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(SimulateRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ServiceServer).Simulate(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/cosmos.tx.v1beta1.Service/Simulate", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ServiceServer).Simulate(ctx, req.(*SimulateRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Service_GetTx_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GetTxRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ServiceServer).GetTx(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/cosmos.tx.v1beta1.Service/GetTx", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ServiceServer).GetTx(ctx, req.(*GetTxRequest)) + } + return interceptor(ctx, in, info, handler) +} + +var _Service_serviceDesc = grpc.ServiceDesc{ + ServiceName: "cosmos.tx.v1beta1.Service", + HandlerType: (*ServiceServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "Simulate", + Handler: _Service_Simulate_Handler, + }, + { + MethodName: "GetTx", + Handler: _Service_GetTx_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "cosmos/tx/v1beta1/service.proto", +} + +func (m *SimulateRequest) 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 *SimulateRequest) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *SimulateRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.Tx != nil { + { + size, err := m.Tx.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintService(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *SimulateResponse) 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 *SimulateResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *SimulateResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.Result != nil { + { + size, err := m.Result.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintService(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } + if m.GasInfo != nil { + { + size, err := m.GasInfo.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintService(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *GetTxRequest) 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 *GetTxRequest) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *GetTxRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Hash) > 0 { + i -= len(m.Hash) + copy(dAtA[i:], m.Hash) + i = encodeVarintService(dAtA, i, uint64(len(m.Hash))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *GetTxResponse) 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 *GetTxResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *GetTxResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.Tx != nil { + { + size, err := m.Tx.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintService(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func encodeVarintService(dAtA []byte, offset int, v uint64) int { + offset -= sovService(v) + base := offset + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return base +} +func (m *SimulateRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Tx != nil { + l = m.Tx.Size() + n += 1 + l + sovService(uint64(l)) + } + return n +} + +func (m *SimulateResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.GasInfo != nil { + l = m.GasInfo.Size() + n += 1 + l + sovService(uint64(l)) + } + if m.Result != nil { + l = m.Result.Size() + n += 1 + l + sovService(uint64(l)) + } + return n +} + +func (m *GetTxRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Hash) + if l > 0 { + n += 1 + l + sovService(uint64(l)) + } + return n +} + +func (m *GetTxResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Tx != nil { + l = m.Tx.Size() + n += 1 + l + sovService(uint64(l)) + } + return n +} + +func sovService(x uint64) (n int) { + return (math_bits.Len64(x|1) + 6) / 7 +} +func sozService(x uint64) (n int) { + return sovService(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (m *SimulateRequest) 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 ErrIntOverflowService + } + 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: SimulateRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: SimulateRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Tx", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowService + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthService + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthService + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Tx == nil { + m.Tx = &Tx{} + } + if err := m.Tx.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipService(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthService + } + if (iNdEx + skippy) < 0 { + return ErrInvalidLengthService + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *SimulateResponse) 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 ErrIntOverflowService + } + 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: SimulateResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: SimulateResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field GasInfo", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowService + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthService + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthService + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.GasInfo == nil { + m.GasInfo = &types.GasInfo{} + } + if err := m.GasInfo.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Result", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowService + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthService + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthService + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Result == nil { + m.Result = &types.Result{} + } + if err := m.Result.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipService(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthService + } + if (iNdEx + skippy) < 0 { + return ErrInvalidLengthService + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *GetTxRequest) 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 ErrIntOverflowService + } + 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: GetTxRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: GetTxRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Hash", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowService + } + 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 ErrInvalidLengthService + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthService + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Hash = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipService(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthService + } + if (iNdEx + skippy) < 0 { + return ErrInvalidLengthService + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *GetTxResponse) 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 ErrIntOverflowService + } + 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: GetTxResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: GetTxResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Tx", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowService + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthService + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthService + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Tx == nil { + m.Tx = &Tx{} + } + if err := m.Tx.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipService(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthService + } + if (iNdEx + skippy) < 0 { + return ErrInvalidLengthService + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func skipService(dAtA []byte) (n int, err error) { + l := len(dAtA) + iNdEx := 0 + depth := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowService + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + wireType := int(wire & 0x7) + switch wireType { + case 0: + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowService + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + iNdEx++ + if dAtA[iNdEx-1] < 0x80 { + break + } + } + case 1: + iNdEx += 8 + case 2: + var length int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowService + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + length |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if length < 0 { + return 0, ErrInvalidLengthService + } + iNdEx += length + case 3: + depth++ + case 4: + if depth == 0 { + return 0, ErrUnexpectedEndOfGroupService + } + depth-- + case 5: + iNdEx += 4 + default: + return 0, fmt.Errorf("proto: illegal wireType %d", wireType) + } + if iNdEx < 0 { + return 0, ErrInvalidLengthService + } + if depth == 0 { + return iNdEx, nil + } + } + return 0, io.ErrUnexpectedEOF +} + +var ( + ErrInvalidLengthService = fmt.Errorf("proto: negative length found during unmarshaling") + ErrIntOverflowService = fmt.Errorf("proto: integer overflow") + ErrUnexpectedEndOfGroupService = fmt.Errorf("proto: unexpected end of group") +) diff --git a/types/tx/service.pb.gw.go b/types/tx/service.pb.gw.go new file mode 100644 index 000000000000..270036363ad5 --- /dev/null +++ b/types/tx/service.pb.gw.go @@ -0,0 +1,264 @@ +// Code generated by protoc-gen-grpc-gateway. DO NOT EDIT. +// source: cosmos/tx/v1beta1/service.proto + +/* +Package tx is a reverse proxy. + +It translates gRPC into RESTful JSON APIs. +*/ +package tx + +import ( + "context" + "io" + "net/http" + + "github.com/golang/protobuf/descriptor" + "github.com/golang/protobuf/proto" + "github.com/grpc-ecosystem/grpc-gateway/runtime" + "github.com/grpc-ecosystem/grpc-gateway/utilities" + "google.golang.org/grpc" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/grpclog" + "google.golang.org/grpc/status" +) + +// Suppress "imported and not used" errors +var _ codes.Code +var _ io.Reader +var _ status.Status +var _ = runtime.String +var _ = utilities.NewDoubleArray +var _ = descriptor.ForMessage + +var ( + filter_Service_Simulate_0 = &utilities.DoubleArray{Encoding: map[string]int{}, Base: []int(nil), Check: []int(nil)} +) + +func request_Service_Simulate_0(ctx context.Context, marshaler runtime.Marshaler, client ServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq SimulateRequest + var metadata runtime.ServerMetadata + + if err := req.ParseForm(); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_Service_Simulate_0); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := client.Simulate(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_Service_Simulate_0(ctx context.Context, marshaler runtime.Marshaler, server ServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq SimulateRequest + var metadata runtime.ServerMetadata + + if err := req.ParseForm(); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_Service_Simulate_0); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := server.Simulate(ctx, &protoReq) + return msg, metadata, err + +} + +func request_Service_GetTx_0(ctx context.Context, marshaler runtime.Marshaler, client ServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq GetTxRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["hash"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "hash") + } + + protoReq.Hash, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "hash", err) + } + + msg, err := client.GetTx(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_Service_GetTx_0(ctx context.Context, marshaler runtime.Marshaler, server ServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq GetTxRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["hash"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "hash") + } + + protoReq.Hash, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "hash", err) + } + + msg, err := server.GetTx(ctx, &protoReq) + return msg, metadata, err + +} + +// RegisterServiceHandlerServer registers the http handlers for service Service to "mux". +// UnaryRPC :call ServiceServer directly. +// StreamingRPC :currently unsupported pending https://github.com/grpc/grpc-go/issues/906. +// Note that using this registration option will cause many gRPC library features (such as grpc.SendHeader, etc) to stop working. Consider using RegisterServiceHandlerFromEndpoint instead. +func RegisterServiceHandlerServer(ctx context.Context, mux *runtime.ServeMux, server ServiceServer) error { + + mux.Handle("POST", pattern_Service_Simulate_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_Service_Simulate_0(rctx, inboundMarshaler, server, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_Service_Simulate_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("GET", pattern_Service_GetTx_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_Service_GetTx_0(rctx, inboundMarshaler, server, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_Service_GetTx_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + return nil +} + +// RegisterServiceHandlerFromEndpoint is same as RegisterServiceHandler but +// automatically dials to "endpoint" and closes the connection when "ctx" gets done. +func RegisterServiceHandlerFromEndpoint(ctx context.Context, mux *runtime.ServeMux, endpoint string, opts []grpc.DialOption) (err error) { + conn, err := grpc.Dial(endpoint, opts...) + if err != nil { + return err + } + defer func() { + if err != nil { + if cerr := conn.Close(); cerr != nil { + grpclog.Infof("Failed to close conn to %s: %v", endpoint, cerr) + } + return + } + go func() { + <-ctx.Done() + if cerr := conn.Close(); cerr != nil { + grpclog.Infof("Failed to close conn to %s: %v", endpoint, cerr) + } + }() + }() + + return RegisterServiceHandler(ctx, mux, conn) +} + +// RegisterServiceHandler registers the http handlers for service Service to "mux". +// The handlers forward requests to the grpc endpoint over "conn". +func RegisterServiceHandler(ctx context.Context, mux *runtime.ServeMux, conn *grpc.ClientConn) error { + return RegisterServiceHandlerClient(ctx, mux, NewServiceClient(conn)) +} + +// RegisterServiceHandlerClient registers the http handlers for service Service +// to "mux". The handlers forward requests to the grpc endpoint over the given implementation of "ServiceClient". +// Note: the gRPC framework executes interceptors within the gRPC handler. If the passed in "ServiceClient" +// doesn't go through the normal gRPC flow (creating a gRPC client etc.) then it will be up to the passed in +// "ServiceClient" to call the correct interceptors. +func RegisterServiceHandlerClient(ctx context.Context, mux *runtime.ServeMux, client ServiceClient) error { + + mux.Handle("POST", pattern_Service_Simulate_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_Service_Simulate_0(rctx, inboundMarshaler, client, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_Service_Simulate_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("GET", pattern_Service_GetTx_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_Service_GetTx_0(rctx, inboundMarshaler, client, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_Service_GetTx_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + return nil +} + +var ( + pattern_Service_Simulate_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"cosmos", "tx", "v1beta1", "simulate"}, "", runtime.AssumeColonVerbOpt(true))) + + pattern_Service_GetTx_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 1, 1, 0, 4, 1, 5, 3}, []string{"cosmos", "tx", "v1beta1", "hash"}, "", runtime.AssumeColonVerbOpt(true))) +) + +var ( + forward_Service_Simulate_0 = runtime.ForwardResponseMessage + + forward_Service_GetTx_0 = runtime.ForwardResponseMessage +) diff --git a/x/auth/tx/service.go b/x/auth/tx/service.go new file mode 100644 index 000000000000..d430dc2b0a38 --- /dev/null +++ b/x/auth/tx/service.go @@ -0,0 +1,111 @@ +package tx + +import ( + "context" + "encoding/hex" + + gogogrpc "github.com/gogo/protobuf/grpc" + "github.com/grpc-ecosystem/grpc-gateway/runtime" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" + + "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/codec" + codectypes "github.com/cosmos/cosmos-sdk/codec/types" + sdk "github.com/cosmos/cosmos-sdk/types" + txtypes "github.com/cosmos/cosmos-sdk/types/tx" +) + +// baseAppSimulateFn is the signature of the Baseapp#Simulate function. +type baseAppSimulateFn func(txBytes []byte) (sdk.GasInfo, *sdk.Result, error) + +// txServer is the server for the protobuf Tx service. +type txServer struct { + clientCtx client.Context + simulate baseAppSimulateFn + interfaceRegistry codectypes.InterfaceRegistry +} + +// NewTxServer creates a new Tx service server. +func NewTxServer(clientCtx client.Context, simulate baseAppSimulateFn, interfaceRegistry codectypes.InterfaceRegistry) txtypes.ServiceServer { + return txServer{ + clientCtx: clientCtx, + simulate: simulate, + interfaceRegistry: interfaceRegistry, + } +} + +var _ txtypes.ServiceServer = txServer{} + +// Simulate implements the ServiceServer.Simulate RPC method. +func (s txServer) Simulate(ctx context.Context, req *txtypes.SimulateRequest) (*txtypes.SimulateResponse, error) { + if req.Tx == nil { + return nil, status.Error(codes.InvalidArgument, "invalid empty tx") + } + + err := req.Tx.UnpackInterfaces(s.interfaceRegistry) + if err != nil { + return nil, err + } + txBytes, err := req.Tx.Marshal() + if err != nil { + return nil, err + } + + gasInfo, result, err := s.simulate(txBytes) + if err != nil { + return nil, err + } + + return &txtypes.SimulateResponse{ + GasInfo: &gasInfo, + Result: result, + }, nil +} + +// GetTx implements the ServiceServer.GetTx RPC method. +func (s txServer) GetTx(ctx context.Context, req *txtypes.GetTxRequest) (*txtypes.GetTxResponse, error) { + // We get hash as a hex string in the request, convert it to bytes. + hash, err := hex.DecodeString(req.Hash) + if err != nil { + return nil, err + } + + // TODO We should also check the proof flag in gRPC header. + // https://github.com/cosmos/cosmos-sdk/issues/7036. + result, err := s.clientCtx.Client.Tx(ctx, hash, false) + if err != nil { + return nil, err + } + + // Create a proto codec, we need it to unmarshal the tx bytes. + cdc := codec.NewProtoCodec(s.clientCtx.InterfaceRegistry) + var protoTx txtypes.Tx + + if err := cdc.UnmarshalBinaryBare(result.Tx, &protoTx); err != nil { + return nil, err + } + + return &txtypes.GetTxResponse{ + Tx: &protoTx, + }, nil +} + +// RegisterTxService registers the tx service on the gRPC router. +func RegisterTxService( + qrt gogogrpc.Server, + clientCtx client.Context, + simulateFn baseAppSimulateFn, + interfaceRegistry codectypes.InterfaceRegistry, +) { + txtypes.RegisterServiceServer( + qrt, + NewTxServer(clientCtx, simulateFn, interfaceRegistry), + ) +} + +// RegisterGRPCGatewayRoutes mounts the tx service's GRPC-gateway routes on the +// given Mux. +func RegisterGRPCGatewayRoutes(clientConn gogogrpc.ClientConn, mux *runtime.ServeMux) { + txtypes.RegisterServiceHandlerClient(context.Background(), mux, txtypes.NewServiceClient(clientConn)) +} diff --git a/x/auth/tx/service_test.go b/x/auth/tx/service_test.go new file mode 100644 index 000000000000..ec51cf0e2bb9 --- /dev/null +++ b/x/auth/tx/service_test.go @@ -0,0 +1,164 @@ +package tx_test + +import ( + "context" + "fmt" + "testing" + + "github.com/stretchr/testify/suite" + + "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/client/flags" + clienttx "github.com/cosmos/cosmos-sdk/client/tx" + codectypes "github.com/cosmos/cosmos-sdk/codec/types" + "github.com/cosmos/cosmos-sdk/testutil/network" + "github.com/cosmos/cosmos-sdk/testutil/testdata" + sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + "github.com/cosmos/cosmos-sdk/types/rest" + "github.com/cosmos/cosmos-sdk/types/tx" + "github.com/cosmos/cosmos-sdk/types/tx/signing" + authclient "github.com/cosmos/cosmos-sdk/x/auth/client" + bankcli "github.com/cosmos/cosmos-sdk/x/bank/client/testutil" + banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" +) + +type IntegrationTestSuite struct { + suite.Suite + + cfg network.Config + network *network.Network + + queryClient tx.ServiceClient +} + +func (s *IntegrationTestSuite) SetupSuite() { + s.T().Log("setting up integration test suite") + + cfg := network.DefaultConfig() + cfg.NumValidators = 1 + + s.cfg = cfg + s.network = network.New(s.T(), cfg) + + s.Require().NotNil(s.network) + + _, err := s.network.WaitForHeight(1) + s.Require().NoError(err) + + s.queryClient = tx.NewServiceClient(s.network.Validators[0].ClientCtx) +} + +func (s *IntegrationTestSuite) TearDownSuite() { + s.T().Log("tearing down integration test suite") + s.network.Cleanup() +} + +func (s IntegrationTestSuite) TestSimulate() { + val := s.network.Validators[0] + + // prepare txBuilder with msg + txBuilder := val.ClientCtx.TxConfig.NewTxBuilder() + feeAmount := sdk.Coins{sdk.NewInt64Coin(s.cfg.BondDenom, 10)} + gasLimit := testdata.NewTestGasLimit() + s.Require().NoError( + txBuilder.SetMsgs(&banktypes.MsgSend{ + FromAddress: val.Address.String(), + ToAddress: val.Address.String(), + Amount: sdk.Coins{sdk.NewInt64Coin(s.cfg.BondDenom, 10)}, + }), + ) + txBuilder.SetFeeAmount(feeAmount) + txBuilder.SetGasLimit(gasLimit) + txBuilder.SetMemo("foobar") + + // setup txFactory + txFactory := clienttx.Factory{}. + WithChainID(val.ClientCtx.ChainID). + WithKeybase(val.ClientCtx.Keyring). + WithTxConfig(val.ClientCtx.TxConfig). + WithSignMode(signing.SignMode_SIGN_MODE_DIRECT) + + // Sign Tx. + err := authclient.SignTx(txFactory, val.ClientCtx, val.Moniker, txBuilder, false) + s.Require().NoError(err) + + // Convert the txBuilder to a tx.Tx. + protoTx, err := txBuilderToProtoTx(txBuilder) + s.Require().NoError(err) + + // Run the simulate gRPC query. + res, err := s.queryClient.Simulate( + context.Background(), + &tx.SimulateRequest{Tx: protoTx}, + ) + s.Require().NoError(err) + + // Check the result and gas used are correct. + s.Require().Equal(len(res.GetResult().GetEvents()), 4) // 1 transfer, 3 messages. + s.Require().True(res.GetGasInfo().GetGasUsed() > 0) // Gas used sometimes change, just check it's not empty. +} + +func (s IntegrationTestSuite) TestGetTx() { + val := s.network.Validators[0] + + // Create a new MsgSend tx from val to itself. + out, err := bankcli.MsgSendExec( + val.ClientCtx, + val.Address, + val.Address, + sdk.NewCoins( + sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10)), + ), + fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), + fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock), + fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()), + fmt.Sprintf("--gas=%d", flags.DefaultGasLimit), + fmt.Sprintf("--%s=foobar", flags.FlagMemo), + ) + s.Require().NoError(err) + var txRes sdk.TxResponse + s.Require().NoError(val.ClientCtx.JSONMarshaler.UnmarshalJSON(out.Bytes(), &txRes)) + s.Require().Equal(uint32(0), txRes.Code) + + s.Require().NoError(s.network.WaitForNextBlock()) + + // Query the tx via gRPC. + grpcRes, err := s.queryClient.GetTx( + context.Background(), + &tx.GetTxRequest{Hash: txRes.TxHash}, + ) + s.Require().NoError(err) + s.Require().Equal("foobar", grpcRes.Tx.Body.Memo) + + // Query the tx via grpc-gateway. + restRes, err := rest.GetRequest(fmt.Sprintf("%s/cosmos/tx/v1beta1/tx/%s", val.APIAddress, txRes.TxHash)) + s.Require().NoError(err) + var getTxRes tx.GetTxResponse + s.Require().NoError(val.ClientCtx.JSONMarshaler.UnmarshalJSON(restRes, &getTxRes)) + s.Require().Equal("foobar", getTxRes.Tx.Body.Memo) +} + +func TestIntegrationTestSuite(t *testing.T) { + suite.Run(t, new(IntegrationTestSuite)) +} + +// txBuilderToProtoTx converts a txBuilder into a proto tx.Tx. +func txBuilderToProtoTx(txBuilder client.TxBuilder) (*tx.Tx, error) { // nolint + intoAnyTx, ok := txBuilder.(codectypes.IntoAny) + if !ok { + return nil, sdkerrors.Wrapf(sdkerrors.ErrInvalidType, "expected %T, got %T", (codectypes.IntoAny)(nil), intoAnyTx) + } + + any := intoAnyTx.AsAny().GetCachedValue() + if any == nil { + return nil, sdkerrors.Wrapf(sdkerrors.ErrInvalidType, "any's cached value is empty") + } + + protoTx, ok := any.(*tx.Tx) + if !ok { + return nil, sdkerrors.Wrapf(sdkerrors.ErrInvalidType, "expected %T, got %T", (codectypes.IntoAny)(nil), intoAnyTx) + } + + return protoTx, nil +}