mirror of
https://github.com/fluencelabs/tendermint
synced 2025-06-01 07:31:20 +00:00
broadcast_tx via grpc
This commit is contained in:
parent
538a50c9e8
commit
db437e7a45
@ -16,6 +16,7 @@ func parseFlags(config cfg.Config, args []string) {
|
||||
fastSync bool
|
||||
skipUPNP bool
|
||||
rpcLaddr string
|
||||
grpcLaddr string
|
||||
logLevel string
|
||||
proxyApp string
|
||||
tmspTransport string
|
||||
@ -30,6 +31,7 @@ func parseFlags(config cfg.Config, args []string) {
|
||||
flags.BoolVar(&fastSync, "fast_sync", config.GetBool("fast_sync"), "Fast blockchain syncing")
|
||||
flags.BoolVar(&skipUPNP, "skip_upnp", config.GetBool("skip_upnp"), "Skip UPNP configuration")
|
||||
flags.StringVar(&rpcLaddr, "rpc_laddr", config.GetString("rpc_laddr"), "RPC listen address. Port required")
|
||||
flags.StringVar(&grpcLaddr, "grpc_laddr", config.GetString("grpc_laddr"), "GRPC listen address (BroadcastTx only). Port required")
|
||||
flags.StringVar(&logLevel, "log_level", config.GetString("log_level"), "Log level")
|
||||
flags.StringVar(&proxyApp, "proxy_app", config.GetString("proxy_app"),
|
||||
"Proxy app address, or 'nilapp' or 'dummy' for local testing.")
|
||||
@ -47,6 +49,7 @@ func parseFlags(config cfg.Config, args []string) {
|
||||
config.Set("fast_sync", fastSync)
|
||||
config.Set("skip_upnp", skipUPNP)
|
||||
config.Set("rpc_laddr", rpcLaddr)
|
||||
config.Set("grpc_laddr", grpcLaddr)
|
||||
config.Set("log_level", logLevel)
|
||||
config.Set("proxy_app", proxyApp)
|
||||
config.Set("tmsp", tmspTransport)
|
||||
|
@ -67,6 +67,7 @@ func GetConfig(rootDir string) cfg.Config {
|
||||
mapConfig.SetDefault("db_dir", rootDir+"/data")
|
||||
mapConfig.SetDefault("log_level", "info")
|
||||
mapConfig.SetDefault("rpc_laddr", "tcp://0.0.0.0:46657")
|
||||
mapConfig.SetDefault("grpc_laddr", "")
|
||||
mapConfig.SetDefault("prof_laddr", "")
|
||||
mapConfig.SetDefault("revision_file", rootDir+"/revision")
|
||||
mapConfig.SetDefault("cs_wal_dir", rootDir+"/data/cs.wal")
|
||||
|
@ -80,6 +80,7 @@ func ResetConfig(localPath string) cfg.Config {
|
||||
mapConfig.SetDefault("db_dir", rootDir+"/data")
|
||||
mapConfig.SetDefault("log_level", "debug")
|
||||
mapConfig.SetDefault("rpc_laddr", "tcp://0.0.0.0:36657")
|
||||
mapConfig.SetDefault("grpc_laddr", "tcp://0.0.0.0:36658")
|
||||
mapConfig.SetDefault("prof_laddr", "")
|
||||
mapConfig.SetDefault("revision_file", rootDir+"/revision")
|
||||
mapConfig.SetDefault("cs_wal_dir", rootDir+"/data/cs.wal")
|
||||
|
12
node/node.go
12
node/node.go
@ -21,6 +21,7 @@ import (
|
||||
mempl "github.com/tendermint/tendermint/mempool"
|
||||
"github.com/tendermint/tendermint/proxy"
|
||||
rpccore "github.com/tendermint/tendermint/rpc/core"
|
||||
grpccore "github.com/tendermint/tendermint/rpc/grpc"
|
||||
sm "github.com/tendermint/tendermint/state"
|
||||
"github.com/tendermint/tendermint/types"
|
||||
"github.com/tendermint/tendermint/version"
|
||||
@ -218,6 +219,17 @@ func (n *Node) StartRPC() ([]net.Listener, error) {
|
||||
}
|
||||
listeners[i] = listener
|
||||
}
|
||||
|
||||
// we expose a simplified api over grpc for convenience to app devs
|
||||
grpcListenAddr := n.config.GetString("grpc_laddr")
|
||||
if grpcListenAddr != "" {
|
||||
listener, err := grpccore.StartGRPCServer(grpcListenAddr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
listeners = append(listeners, listener)
|
||||
}
|
||||
|
||||
return listeners, nil
|
||||
}
|
||||
|
||||
|
18
rpc/grpc/api.go
Normal file
18
rpc/grpc/api.go
Normal file
@ -0,0 +1,18 @@
|
||||
package core_grpc
|
||||
|
||||
import (
|
||||
core "github.com/tendermint/tendermint/rpc/core"
|
||||
|
||||
context "golang.org/x/net/context"
|
||||
)
|
||||
|
||||
type broadcastAPI struct {
|
||||
}
|
||||
|
||||
func (bapi *broadcastAPI) BroadcastTx(ctx context.Context, req *RequestBroadcastTx) (*ResponseBroadcastTx, error) {
|
||||
res, err := core.BroadcastTxCommit(req.Tx)
|
||||
if res == nil {
|
||||
return nil, err
|
||||
}
|
||||
return &ResponseBroadcastTx{uint64(res.Code), res.Data, res.Log}, err
|
||||
}
|
44
rpc/grpc/client_server.go
Normal file
44
rpc/grpc/client_server.go
Normal file
@ -0,0 +1,44 @@
|
||||
package core_grpc
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"google.golang.org/grpc"
|
||||
|
||||
. "github.com/tendermint/go-common"
|
||||
)
|
||||
|
||||
// Start the grpcServer in a go routine
|
||||
func StartGRPCServer(protoAddr string) (net.Listener, error) {
|
||||
parts := strings.SplitN(protoAddr, "://", 2)
|
||||
if len(parts) != 2 {
|
||||
return nil, fmt.Errorf("Invalid listen address for grpc server (did you forget a tcp:// prefix?) : %s", protoAddr)
|
||||
}
|
||||
proto, addr := parts[0], parts[1]
|
||||
ln, err := net.Listen(proto, addr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
grpcServer := grpc.NewServer()
|
||||
RegisterBroadcastAPIServer(grpcServer, &broadcastAPI{})
|
||||
go grpcServer.Serve(ln)
|
||||
|
||||
return ln, nil
|
||||
}
|
||||
|
||||
// Start the client by dialing the server
|
||||
func StartGRPCClient(protoAddr string) BroadcastAPIClient {
|
||||
conn, err := grpc.Dial(protoAddr, grpc.WithInsecure(), grpc.WithDialer(dialerFunc))
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return NewBroadcastAPIClient(conn)
|
||||
}
|
||||
|
||||
func dialerFunc(addr string, timeout time.Duration) (net.Conn, error) {
|
||||
return Connect(addr)
|
||||
}
|
336
rpc/grpc/types.pb.go
Normal file
336
rpc/grpc/types.pb.go
Normal file
@ -0,0 +1,336 @@
|
||||
// Code generated by protoc-gen-go.
|
||||
// source: types.proto
|
||||
// DO NOT EDIT!
|
||||
|
||||
/*
|
||||
Package core_grpc is a generated protocol buffer package.
|
||||
|
||||
It is generated from these files:
|
||||
types.proto
|
||||
|
||||
It has these top-level messages:
|
||||
Request
|
||||
RequestBroadcastTx
|
||||
Response
|
||||
ResponseBroadcastTx
|
||||
*/
|
||||
package core_grpc
|
||||
|
||||
import proto "github.com/golang/protobuf/proto"
|
||||
import fmt "fmt"
|
||||
import math "math"
|
||||
|
||||
import (
|
||||
context "golang.org/x/net/context"
|
||||
grpc "google.golang.org/grpc"
|
||||
)
|
||||
|
||||
// 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.ProtoPackageIsVersion2 // please upgrade the proto package
|
||||
|
||||
type Request struct {
|
||||
// Types that are valid to be assigned to Value:
|
||||
// *Request_BroadcastTx
|
||||
Value isRequest_Value `protobuf_oneof:"value"`
|
||||
}
|
||||
|
||||
func (m *Request) Reset() { *m = Request{} }
|
||||
func (m *Request) String() string { return proto.CompactTextString(m) }
|
||||
func (*Request) ProtoMessage() {}
|
||||
func (*Request) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{0} }
|
||||
|
||||
type isRequest_Value interface {
|
||||
isRequest_Value()
|
||||
}
|
||||
|
||||
type Request_BroadcastTx struct {
|
||||
BroadcastTx *RequestBroadcastTx `protobuf:"bytes,1,opt,name=broadcast_tx,json=broadcastTx,oneof"`
|
||||
}
|
||||
|
||||
func (*Request_BroadcastTx) isRequest_Value() {}
|
||||
|
||||
func (m *Request) GetValue() isRequest_Value {
|
||||
if m != nil {
|
||||
return m.Value
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *Request) GetBroadcastTx() *RequestBroadcastTx {
|
||||
if x, ok := m.GetValue().(*Request_BroadcastTx); ok {
|
||||
return x.BroadcastTx
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// XXX_OneofFuncs is for the internal use of the proto package.
|
||||
func (*Request) XXX_OneofFuncs() (func(msg proto.Message, b *proto.Buffer) error, func(msg proto.Message, tag, wire int, b *proto.Buffer) (bool, error), func(msg proto.Message) (n int), []interface{}) {
|
||||
return _Request_OneofMarshaler, _Request_OneofUnmarshaler, _Request_OneofSizer, []interface{}{
|
||||
(*Request_BroadcastTx)(nil),
|
||||
}
|
||||
}
|
||||
|
||||
func _Request_OneofMarshaler(msg proto.Message, b *proto.Buffer) error {
|
||||
m := msg.(*Request)
|
||||
// value
|
||||
switch x := m.Value.(type) {
|
||||
case *Request_BroadcastTx:
|
||||
b.EncodeVarint(1<<3 | proto.WireBytes)
|
||||
if err := b.EncodeMessage(x.BroadcastTx); err != nil {
|
||||
return err
|
||||
}
|
||||
case nil:
|
||||
default:
|
||||
return fmt.Errorf("Request.Value has unexpected type %T", x)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func _Request_OneofUnmarshaler(msg proto.Message, tag, wire int, b *proto.Buffer) (bool, error) {
|
||||
m := msg.(*Request)
|
||||
switch tag {
|
||||
case 1: // value.broadcast_tx
|
||||
if wire != proto.WireBytes {
|
||||
return true, proto.ErrInternalBadWireType
|
||||
}
|
||||
msg := new(RequestBroadcastTx)
|
||||
err := b.DecodeMessage(msg)
|
||||
m.Value = &Request_BroadcastTx{msg}
|
||||
return true, err
|
||||
default:
|
||||
return false, nil
|
||||
}
|
||||
}
|
||||
|
||||
func _Request_OneofSizer(msg proto.Message) (n int) {
|
||||
m := msg.(*Request)
|
||||
// value
|
||||
switch x := m.Value.(type) {
|
||||
case *Request_BroadcastTx:
|
||||
s := proto.Size(x.BroadcastTx)
|
||||
n += proto.SizeVarint(1<<3 | proto.WireBytes)
|
||||
n += proto.SizeVarint(uint64(s))
|
||||
n += s
|
||||
case nil:
|
||||
default:
|
||||
panic(fmt.Sprintf("proto: unexpected type %T in oneof", x))
|
||||
}
|
||||
return n
|
||||
}
|
||||
|
||||
type RequestBroadcastTx struct {
|
||||
Tx []byte `protobuf:"bytes,1,opt,name=tx,proto3" json:"tx,omitempty"`
|
||||
}
|
||||
|
||||
func (m *RequestBroadcastTx) Reset() { *m = RequestBroadcastTx{} }
|
||||
func (m *RequestBroadcastTx) String() string { return proto.CompactTextString(m) }
|
||||
func (*RequestBroadcastTx) ProtoMessage() {}
|
||||
func (*RequestBroadcastTx) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{1} }
|
||||
|
||||
type Response struct {
|
||||
// Types that are valid to be assigned to Value:
|
||||
// *Response_BroadcastTx
|
||||
Value isResponse_Value `protobuf_oneof:"value"`
|
||||
}
|
||||
|
||||
func (m *Response) Reset() { *m = Response{} }
|
||||
func (m *Response) String() string { return proto.CompactTextString(m) }
|
||||
func (*Response) ProtoMessage() {}
|
||||
func (*Response) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{2} }
|
||||
|
||||
type isResponse_Value interface {
|
||||
isResponse_Value()
|
||||
}
|
||||
|
||||
type Response_BroadcastTx struct {
|
||||
BroadcastTx *ResponseBroadcastTx `protobuf:"bytes,1,opt,name=broadcast_tx,json=broadcastTx,oneof"`
|
||||
}
|
||||
|
||||
func (*Response_BroadcastTx) isResponse_Value() {}
|
||||
|
||||
func (m *Response) GetValue() isResponse_Value {
|
||||
if m != nil {
|
||||
return m.Value
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *Response) GetBroadcastTx() *ResponseBroadcastTx {
|
||||
if x, ok := m.GetValue().(*Response_BroadcastTx); ok {
|
||||
return x.BroadcastTx
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// XXX_OneofFuncs is for the internal use of the proto package.
|
||||
func (*Response) XXX_OneofFuncs() (func(msg proto.Message, b *proto.Buffer) error, func(msg proto.Message, tag, wire int, b *proto.Buffer) (bool, error), func(msg proto.Message) (n int), []interface{}) {
|
||||
return _Response_OneofMarshaler, _Response_OneofUnmarshaler, _Response_OneofSizer, []interface{}{
|
||||
(*Response_BroadcastTx)(nil),
|
||||
}
|
||||
}
|
||||
|
||||
func _Response_OneofMarshaler(msg proto.Message, b *proto.Buffer) error {
|
||||
m := msg.(*Response)
|
||||
// value
|
||||
switch x := m.Value.(type) {
|
||||
case *Response_BroadcastTx:
|
||||
b.EncodeVarint(1<<3 | proto.WireBytes)
|
||||
if err := b.EncodeMessage(x.BroadcastTx); err != nil {
|
||||
return err
|
||||
}
|
||||
case nil:
|
||||
default:
|
||||
return fmt.Errorf("Response.Value has unexpected type %T", x)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func _Response_OneofUnmarshaler(msg proto.Message, tag, wire int, b *proto.Buffer) (bool, error) {
|
||||
m := msg.(*Response)
|
||||
switch tag {
|
||||
case 1: // value.broadcast_tx
|
||||
if wire != proto.WireBytes {
|
||||
return true, proto.ErrInternalBadWireType
|
||||
}
|
||||
msg := new(ResponseBroadcastTx)
|
||||
err := b.DecodeMessage(msg)
|
||||
m.Value = &Response_BroadcastTx{msg}
|
||||
return true, err
|
||||
default:
|
||||
return false, nil
|
||||
}
|
||||
}
|
||||
|
||||
func _Response_OneofSizer(msg proto.Message) (n int) {
|
||||
m := msg.(*Response)
|
||||
// value
|
||||
switch x := m.Value.(type) {
|
||||
case *Response_BroadcastTx:
|
||||
s := proto.Size(x.BroadcastTx)
|
||||
n += proto.SizeVarint(1<<3 | proto.WireBytes)
|
||||
n += proto.SizeVarint(uint64(s))
|
||||
n += s
|
||||
case nil:
|
||||
default:
|
||||
panic(fmt.Sprintf("proto: unexpected type %T in oneof", x))
|
||||
}
|
||||
return n
|
||||
}
|
||||
|
||||
type ResponseBroadcastTx struct {
|
||||
Code uint64 `protobuf:"varint,1,opt,name=code" json:"code,omitempty"`
|
||||
Data []byte `protobuf:"bytes,2,opt,name=data,proto3" json:"data,omitempty"`
|
||||
Log string `protobuf:"bytes,3,opt,name=log" json:"log,omitempty"`
|
||||
}
|
||||
|
||||
func (m *ResponseBroadcastTx) Reset() { *m = ResponseBroadcastTx{} }
|
||||
func (m *ResponseBroadcastTx) String() string { return proto.CompactTextString(m) }
|
||||
func (*ResponseBroadcastTx) ProtoMessage() {}
|
||||
func (*ResponseBroadcastTx) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{3} }
|
||||
|
||||
func init() {
|
||||
proto.RegisterType((*Request)(nil), "core_grpc.Request")
|
||||
proto.RegisterType((*RequestBroadcastTx)(nil), "core_grpc.RequestBroadcastTx")
|
||||
proto.RegisterType((*Response)(nil), "core_grpc.Response")
|
||||
proto.RegisterType((*ResponseBroadcastTx)(nil), "core_grpc.ResponseBroadcastTx")
|
||||
}
|
||||
|
||||
// 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.SupportPackageIsVersion3
|
||||
|
||||
// Client API for BroadcastAPI service
|
||||
|
||||
type BroadcastAPIClient interface {
|
||||
BroadcastTx(ctx context.Context, in *RequestBroadcastTx, opts ...grpc.CallOption) (*ResponseBroadcastTx, error)
|
||||
}
|
||||
|
||||
type broadcastAPIClient struct {
|
||||
cc *grpc.ClientConn
|
||||
}
|
||||
|
||||
func NewBroadcastAPIClient(cc *grpc.ClientConn) BroadcastAPIClient {
|
||||
return &broadcastAPIClient{cc}
|
||||
}
|
||||
|
||||
func (c *broadcastAPIClient) BroadcastTx(ctx context.Context, in *RequestBroadcastTx, opts ...grpc.CallOption) (*ResponseBroadcastTx, error) {
|
||||
out := new(ResponseBroadcastTx)
|
||||
err := grpc.Invoke(ctx, "/core_grpc.BroadcastAPI/BroadcastTx", in, out, c.cc, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// Server API for BroadcastAPI service
|
||||
|
||||
type BroadcastAPIServer interface {
|
||||
BroadcastTx(context.Context, *RequestBroadcastTx) (*ResponseBroadcastTx, error)
|
||||
}
|
||||
|
||||
func RegisterBroadcastAPIServer(s *grpc.Server, srv BroadcastAPIServer) {
|
||||
s.RegisterService(&_BroadcastAPI_serviceDesc, srv)
|
||||
}
|
||||
|
||||
func _BroadcastAPI_BroadcastTx_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(RequestBroadcastTx)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(BroadcastAPIServer).BroadcastTx(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: "/core_grpc.BroadcastAPI/BroadcastTx",
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(BroadcastAPIServer).BroadcastTx(ctx, req.(*RequestBroadcastTx))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
var _BroadcastAPI_serviceDesc = grpc.ServiceDesc{
|
||||
ServiceName: "core_grpc.BroadcastAPI",
|
||||
HandlerType: (*BroadcastAPIServer)(nil),
|
||||
Methods: []grpc.MethodDesc{
|
||||
{
|
||||
MethodName: "BroadcastTx",
|
||||
Handler: _BroadcastAPI_BroadcastTx_Handler,
|
||||
},
|
||||
},
|
||||
Streams: []grpc.StreamDesc{},
|
||||
Metadata: fileDescriptor0,
|
||||
}
|
||||
|
||||
func init() { proto.RegisterFile("types.proto", fileDescriptor0) }
|
||||
|
||||
var fileDescriptor0 = []byte{
|
||||
// 222 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xe2, 0xe2, 0x2e, 0xa9, 0x2c, 0x48,
|
||||
0x2d, 0xd6, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0xe2, 0x4c, 0xce, 0x2f, 0x4a, 0x8d, 0x4f, 0x2f,
|
||||
0x2a, 0x48, 0x56, 0x0a, 0xe3, 0x62, 0x0f, 0x4a, 0x2d, 0x2c, 0x4d, 0x2d, 0x2e, 0x11, 0x72, 0xe2,
|
||||
0xe2, 0x49, 0x2a, 0xca, 0x4f, 0x4c, 0x49, 0x4e, 0x2c, 0x2e, 0x89, 0x2f, 0xa9, 0x90, 0x60, 0x54,
|
||||
0x60, 0xd4, 0xe0, 0x36, 0x92, 0xd5, 0x83, 0x2b, 0xd6, 0x83, 0xaa, 0x74, 0x82, 0xa9, 0x0a, 0xa9,
|
||||
0xf0, 0x60, 0x08, 0xe2, 0x4e, 0x42, 0x70, 0x9d, 0xd8, 0xb9, 0x58, 0xcb, 0x12, 0x73, 0x4a, 0x53,
|
||||
0x95, 0x54, 0xb8, 0x84, 0x30, 0x55, 0x0b, 0xf1, 0x71, 0x31, 0x41, 0x0d, 0xe6, 0x09, 0x02, 0xb2,
|
||||
0x94, 0x22, 0xb8, 0x38, 0x82, 0x52, 0x8b, 0x0b, 0xf2, 0xf3, 0x8a, 0x53, 0x85, 0x9c, 0xb1, 0x5a,
|
||||
0x2f, 0x87, 0x62, 0x3d, 0x44, 0x29, 0x31, 0xf6, 0xfb, 0x73, 0x09, 0x63, 0x51, 0x2e, 0x24, 0xc4,
|
||||
0xc5, 0x92, 0x9c, 0x9f, 0x92, 0x0a, 0x36, 0x9c, 0x25, 0x08, 0xcc, 0x06, 0x89, 0xa5, 0x24, 0x96,
|
||||
0x24, 0x4a, 0x30, 0x81, 0x9d, 0x05, 0x66, 0x0b, 0x09, 0x70, 0x31, 0xe7, 0xe4, 0xa7, 0x4b, 0x30,
|
||||
0x03, 0x85, 0x38, 0x83, 0x40, 0x4c, 0xa3, 0x18, 0x2e, 0x1e, 0xb8, 0x41, 0x8e, 0x01, 0x9e, 0x42,
|
||||
0x3e, 0x5c, 0xdc, 0xc8, 0x06, 0xe3, 0x0f, 0x26, 0x29, 0x02, 0xde, 0x48, 0x62, 0x03, 0x47, 0x8c,
|
||||
0x31, 0x20, 0x00, 0x00, 0xff, 0xff, 0xb2, 0x77, 0xda, 0x85, 0xa7, 0x01, 0x00, 0x00,
|
||||
}
|
41
rpc/grpc/types.proto
Normal file
41
rpc/grpc/types.proto
Normal file
@ -0,0 +1,41 @@
|
||||
syntax = "proto3";
|
||||
package core_grpc;
|
||||
|
||||
//----------------------------------------
|
||||
// Message types
|
||||
|
||||
//----------------------------------------
|
||||
// Request types
|
||||
|
||||
message Request {
|
||||
oneof value{
|
||||
RequestBroadcastTx broadcast_tx = 1;
|
||||
}
|
||||
}
|
||||
|
||||
message RequestBroadcastTx {
|
||||
bytes tx = 1;
|
||||
}
|
||||
|
||||
//----------------------------------------
|
||||
// Response types
|
||||
|
||||
|
||||
message Response {
|
||||
oneof value{
|
||||
ResponseBroadcastTx broadcast_tx = 1;
|
||||
}
|
||||
}
|
||||
|
||||
message ResponseBroadcastTx{
|
||||
uint64 code = 1; // TODO: import tmsp ...
|
||||
bytes data = 2;
|
||||
string log = 3;
|
||||
}
|
||||
|
||||
//----------------------------------------
|
||||
// Service Definition
|
||||
|
||||
service BroadcastAPI {
|
||||
rpc BroadcastTx(RequestBroadcastTx) returns (ResponseBroadcastTx) ;
|
||||
}
|
21
rpc/test/grpc_test.go
Normal file
21
rpc/test/grpc_test.go
Normal file
@ -0,0 +1,21 @@
|
||||
package rpctest
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"golang.org/x/net/context"
|
||||
|
||||
"github.com/tendermint/tendermint/rpc/grpc"
|
||||
)
|
||||
|
||||
//-------------------------------------------
|
||||
|
||||
func TestBroadcastTx(t *testing.T) {
|
||||
res, err := clientGRPC.BroadcastTx(context.Background(), &core_grpc.RequestBroadcastTx{[]byte("this is a tx")})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if res.Code != 0 {
|
||||
t.Fatalf("Non-zero code: %d", res.Code)
|
||||
}
|
||||
}
|
@ -13,6 +13,7 @@ import (
|
||||
"github.com/tendermint/tendermint/config/tendermint_test"
|
||||
nm "github.com/tendermint/tendermint/node"
|
||||
ctypes "github.com/tendermint/tendermint/rpc/core/types"
|
||||
"github.com/tendermint/tendermint/rpc/grpc"
|
||||
)
|
||||
|
||||
// global variables for use across all tests
|
||||
@ -24,8 +25,10 @@ var (
|
||||
requestAddr string
|
||||
websocketAddr string
|
||||
websocketEndpoint string
|
||||
grpcAddr string
|
||||
clientURI *client.ClientURI
|
||||
clientJSON *client.ClientJSONRPC
|
||||
clientGRPC core_grpc.BroadcastAPIClient
|
||||
)
|
||||
|
||||
// initialize config and create new node
|
||||
@ -33,12 +36,14 @@ func init() {
|
||||
config = tendermint_test.ResetConfig("rpc_test_client_test")
|
||||
chainID = config.GetString("chain_id")
|
||||
rpcAddr = config.GetString("rpc_laddr")
|
||||
grpcAddr = config.GetString("grpc_laddr")
|
||||
requestAddr = rpcAddr
|
||||
websocketAddr = rpcAddr
|
||||
websocketEndpoint = "/websocket"
|
||||
|
||||
clientURI = client.NewClientURI(requestAddr)
|
||||
clientJSON = client.NewClientJSONRPC(requestAddr)
|
||||
clientGRPC = core_grpc.StartGRPCClient(grpcAddr)
|
||||
|
||||
// TODO: change consensus/state.go timeouts to be shorter
|
||||
|
||||
@ -59,6 +64,8 @@ func newNode(ready chan struct{}) {
|
||||
|
||||
// Run the RPC server.
|
||||
node.StartRPC()
|
||||
time.Sleep(time.Second)
|
||||
|
||||
ready <- struct{}{}
|
||||
|
||||
// Sleep forever
|
||||
|
@ -9,10 +9,37 @@ TESTNAME=$1
|
||||
|
||||
function sendTx() {
|
||||
TX=$1
|
||||
RESPONSE=`curl -s localhost:46657/broadcast_tx_commit?tx=\"$TX\"`
|
||||
CODE=`echo $RESPONSE | jq .result[1].code`
|
||||
ERROR=`echo $RESPONSE | jq .error`
|
||||
ERROR=$(echo "$ERROR" | tr -d '"') # remove surrounding quotes
|
||||
if [[ "$GRPC_BROADCAST_TX" == "" ]]; then
|
||||
RESPONSE=`curl -s localhost:46657/broadcast_tx_commit?tx=\"$TX\"`
|
||||
CODE=`echo $RESPONSE | jq .result[1].code`
|
||||
ERROR=`echo $RESPONSE | jq .error`
|
||||
ERROR=$(echo "$ERROR" | tr -d '"') # remove surrounding quotes
|
||||
else
|
||||
RESPONSE=`go run grpc_client.go $TX`
|
||||
echo $RESPONSE | jq . &> /dev/null
|
||||
IS_JSON=$?
|
||||
if [[ "$IS_JSON" != "0" ]]; then
|
||||
ERROR="$RESPONSE"
|
||||
else
|
||||
ERROR="" # reset
|
||||
fi
|
||||
|
||||
if [[ "$RESPONSE" == "{}" ]]; then
|
||||
# protobuf auto adds `omitempty` to everything so code OK and empty data/log
|
||||
# will not even show when marshalled into json
|
||||
# apparently we can use github.com/golang/protobuf/jsonpb to do the marshalling ...
|
||||
CODE=0
|
||||
else
|
||||
# this wont actually work if theres an error ...
|
||||
CODE=`echo $RESPONSE | jq .code`
|
||||
fi
|
||||
#echo "-------"
|
||||
#echo "TX $TX"
|
||||
#echo "RESPONSE $RESPONSE"
|
||||
#echo "CODE $CODE"
|
||||
#echo "ERROR $ERROR"
|
||||
#echo "----"
|
||||
fi
|
||||
}
|
||||
|
||||
# 0 should pass once and get in block, with no error
|
||||
|
36
test/app/grpc_client.go
Normal file
36
test/app/grpc_client.go
Normal file
@ -0,0 +1,36 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"golang.org/x/net/context"
|
||||
|
||||
"github.com/tendermint/go-wire"
|
||||
"github.com/tendermint/tendermint/rpc/grpc"
|
||||
)
|
||||
|
||||
var grpcAddr = "tcp://localhost:36656"
|
||||
|
||||
func main() {
|
||||
args := os.Args
|
||||
if len(args) == 1 {
|
||||
fmt.Println("Must enter a transaction to send (hex)")
|
||||
os.Exit(1)
|
||||
}
|
||||
tx := args[1]
|
||||
txBytes, err := hex.DecodeString(tx)
|
||||
if err != nil {
|
||||
fmt.Println("Invalid hex", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
clientGRPC := core_grpc.StartGRPCClient(grpcAddr)
|
||||
res, err := clientGRPC.BroadcastTx(context.Background(), &core_grpc.RequestBroadcastTx{txBytes})
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
os.Exit(1)
|
||||
}
|
||||
fmt.Println(string(wire.JSONBytes(res)))
|
||||
}
|
@ -77,6 +77,23 @@ function counter_over_grpc() {
|
||||
kill -9 $pid_counter $pid_tendermint
|
||||
}
|
||||
|
||||
function counter_over_grpc_grpc() {
|
||||
rm -rf $TMROOT
|
||||
tendermint init
|
||||
echo "Starting counter and tendermint"
|
||||
counter --serial --tmsp grpc > /dev/null &
|
||||
pid_counter=$!
|
||||
GRPC_PORT=36656
|
||||
tendermint node --tmsp grpc --grpc_laddr tcp://localhost:$GRPC_PORT > tendermint.log &
|
||||
pid_tendermint=$!
|
||||
sleep 5
|
||||
|
||||
echo "running test"
|
||||
GRPC_BROADCAST_TX=true bash counter_test.sh "Counter over GRPC via GRPC BroadcastTx"
|
||||
|
||||
kill -9 $pid_counter $pid_tendermint
|
||||
}
|
||||
|
||||
cd $GOPATH/src/github.com/tendermint/tendermint/test/app
|
||||
|
||||
case "$1" in
|
||||
@ -92,6 +109,9 @@ case "$1" in
|
||||
"counter_over_grpc")
|
||||
counter_over_grpc
|
||||
;;
|
||||
"counter_over_grpc_grpc")
|
||||
counter_over_grpc_grpc
|
||||
;;
|
||||
*)
|
||||
echo "Running all"
|
||||
dummy_over_socket
|
||||
@ -101,5 +121,7 @@ case "$1" in
|
||||
counter_over_socket
|
||||
echo ""
|
||||
counter_over_grpc
|
||||
echo ""
|
||||
counter_over_grpc_grpc
|
||||
esac
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user