mirror of
https://github.com/fluencelabs/tendermint
synced 2025-06-04 17:11:19 +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
|
fastSync bool
|
||||||
skipUPNP bool
|
skipUPNP bool
|
||||||
rpcLaddr string
|
rpcLaddr string
|
||||||
|
grpcLaddr string
|
||||||
logLevel string
|
logLevel string
|
||||||
proxyApp string
|
proxyApp string
|
||||||
tmspTransport 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(&fastSync, "fast_sync", config.GetBool("fast_sync"), "Fast blockchain syncing")
|
||||||
flags.BoolVar(&skipUPNP, "skip_upnp", config.GetBool("skip_upnp"), "Skip UPNP configuration")
|
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(&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(&logLevel, "log_level", config.GetString("log_level"), "Log level")
|
||||||
flags.StringVar(&proxyApp, "proxy_app", config.GetString("proxy_app"),
|
flags.StringVar(&proxyApp, "proxy_app", config.GetString("proxy_app"),
|
||||||
"Proxy app address, or 'nilapp' or 'dummy' for local testing.")
|
"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("fast_sync", fastSync)
|
||||||
config.Set("skip_upnp", skipUPNP)
|
config.Set("skip_upnp", skipUPNP)
|
||||||
config.Set("rpc_laddr", rpcLaddr)
|
config.Set("rpc_laddr", rpcLaddr)
|
||||||
|
config.Set("grpc_laddr", grpcLaddr)
|
||||||
config.Set("log_level", logLevel)
|
config.Set("log_level", logLevel)
|
||||||
config.Set("proxy_app", proxyApp)
|
config.Set("proxy_app", proxyApp)
|
||||||
config.Set("tmsp", tmspTransport)
|
config.Set("tmsp", tmspTransport)
|
||||||
|
@ -67,6 +67,7 @@ func GetConfig(rootDir string) cfg.Config {
|
|||||||
mapConfig.SetDefault("db_dir", rootDir+"/data")
|
mapConfig.SetDefault("db_dir", rootDir+"/data")
|
||||||
mapConfig.SetDefault("log_level", "info")
|
mapConfig.SetDefault("log_level", "info")
|
||||||
mapConfig.SetDefault("rpc_laddr", "tcp://0.0.0.0:46657")
|
mapConfig.SetDefault("rpc_laddr", "tcp://0.0.0.0:46657")
|
||||||
|
mapConfig.SetDefault("grpc_laddr", "")
|
||||||
mapConfig.SetDefault("prof_laddr", "")
|
mapConfig.SetDefault("prof_laddr", "")
|
||||||
mapConfig.SetDefault("revision_file", rootDir+"/revision")
|
mapConfig.SetDefault("revision_file", rootDir+"/revision")
|
||||||
mapConfig.SetDefault("cs_wal_dir", rootDir+"/data/cs.wal")
|
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("db_dir", rootDir+"/data")
|
||||||
mapConfig.SetDefault("log_level", "debug")
|
mapConfig.SetDefault("log_level", "debug")
|
||||||
mapConfig.SetDefault("rpc_laddr", "tcp://0.0.0.0:36657")
|
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("prof_laddr", "")
|
||||||
mapConfig.SetDefault("revision_file", rootDir+"/revision")
|
mapConfig.SetDefault("revision_file", rootDir+"/revision")
|
||||||
mapConfig.SetDefault("cs_wal_dir", rootDir+"/data/cs.wal")
|
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"
|
mempl "github.com/tendermint/tendermint/mempool"
|
||||||
"github.com/tendermint/tendermint/proxy"
|
"github.com/tendermint/tendermint/proxy"
|
||||||
rpccore "github.com/tendermint/tendermint/rpc/core"
|
rpccore "github.com/tendermint/tendermint/rpc/core"
|
||||||
|
grpccore "github.com/tendermint/tendermint/rpc/grpc"
|
||||||
sm "github.com/tendermint/tendermint/state"
|
sm "github.com/tendermint/tendermint/state"
|
||||||
"github.com/tendermint/tendermint/types"
|
"github.com/tendermint/tendermint/types"
|
||||||
"github.com/tendermint/tendermint/version"
|
"github.com/tendermint/tendermint/version"
|
||||||
@ -218,6 +219,17 @@ func (n *Node) StartRPC() ([]net.Listener, error) {
|
|||||||
}
|
}
|
||||||
listeners[i] = listener
|
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
|
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"
|
"github.com/tendermint/tendermint/config/tendermint_test"
|
||||||
nm "github.com/tendermint/tendermint/node"
|
nm "github.com/tendermint/tendermint/node"
|
||||||
ctypes "github.com/tendermint/tendermint/rpc/core/types"
|
ctypes "github.com/tendermint/tendermint/rpc/core/types"
|
||||||
|
"github.com/tendermint/tendermint/rpc/grpc"
|
||||||
)
|
)
|
||||||
|
|
||||||
// global variables for use across all tests
|
// global variables for use across all tests
|
||||||
@ -24,8 +25,10 @@ var (
|
|||||||
requestAddr string
|
requestAddr string
|
||||||
websocketAddr string
|
websocketAddr string
|
||||||
websocketEndpoint string
|
websocketEndpoint string
|
||||||
|
grpcAddr string
|
||||||
clientURI *client.ClientURI
|
clientURI *client.ClientURI
|
||||||
clientJSON *client.ClientJSONRPC
|
clientJSON *client.ClientJSONRPC
|
||||||
|
clientGRPC core_grpc.BroadcastAPIClient
|
||||||
)
|
)
|
||||||
|
|
||||||
// initialize config and create new node
|
// initialize config and create new node
|
||||||
@ -33,12 +36,14 @@ func init() {
|
|||||||
config = tendermint_test.ResetConfig("rpc_test_client_test")
|
config = tendermint_test.ResetConfig("rpc_test_client_test")
|
||||||
chainID = config.GetString("chain_id")
|
chainID = config.GetString("chain_id")
|
||||||
rpcAddr = config.GetString("rpc_laddr")
|
rpcAddr = config.GetString("rpc_laddr")
|
||||||
|
grpcAddr = config.GetString("grpc_laddr")
|
||||||
requestAddr = rpcAddr
|
requestAddr = rpcAddr
|
||||||
websocketAddr = rpcAddr
|
websocketAddr = rpcAddr
|
||||||
websocketEndpoint = "/websocket"
|
websocketEndpoint = "/websocket"
|
||||||
|
|
||||||
clientURI = client.NewClientURI(requestAddr)
|
clientURI = client.NewClientURI(requestAddr)
|
||||||
clientJSON = client.NewClientJSONRPC(requestAddr)
|
clientJSON = client.NewClientJSONRPC(requestAddr)
|
||||||
|
clientGRPC = core_grpc.StartGRPCClient(grpcAddr)
|
||||||
|
|
||||||
// TODO: change consensus/state.go timeouts to be shorter
|
// TODO: change consensus/state.go timeouts to be shorter
|
||||||
|
|
||||||
@ -59,6 +64,8 @@ func newNode(ready chan struct{}) {
|
|||||||
|
|
||||||
// Run the RPC server.
|
// Run the RPC server.
|
||||||
node.StartRPC()
|
node.StartRPC()
|
||||||
|
time.Sleep(time.Second)
|
||||||
|
|
||||||
ready <- struct{}{}
|
ready <- struct{}{}
|
||||||
|
|
||||||
// Sleep forever
|
// Sleep forever
|
||||||
|
@ -9,10 +9,37 @@ TESTNAME=$1
|
|||||||
|
|
||||||
function sendTx() {
|
function sendTx() {
|
||||||
TX=$1
|
TX=$1
|
||||||
RESPONSE=`curl -s localhost:46657/broadcast_tx_commit?tx=\"$TX\"`
|
if [[ "$GRPC_BROADCAST_TX" == "" ]]; then
|
||||||
CODE=`echo $RESPONSE | jq .result[1].code`
|
RESPONSE=`curl -s localhost:46657/broadcast_tx_commit?tx=\"$TX\"`
|
||||||
ERROR=`echo $RESPONSE | jq .error`
|
CODE=`echo $RESPONSE | jq .result[1].code`
|
||||||
ERROR=$(echo "$ERROR" | tr -d '"') # remove surrounding quotes
|
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
|
# 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
|
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
|
cd $GOPATH/src/github.com/tendermint/tendermint/test/app
|
||||||
|
|
||||||
case "$1" in
|
case "$1" in
|
||||||
@ -92,6 +109,9 @@ case "$1" in
|
|||||||
"counter_over_grpc")
|
"counter_over_grpc")
|
||||||
counter_over_grpc
|
counter_over_grpc
|
||||||
;;
|
;;
|
||||||
|
"counter_over_grpc_grpc")
|
||||||
|
counter_over_grpc_grpc
|
||||||
|
;;
|
||||||
*)
|
*)
|
||||||
echo "Running all"
|
echo "Running all"
|
||||||
dummy_over_socket
|
dummy_over_socket
|
||||||
@ -101,5 +121,7 @@ case "$1" in
|
|||||||
counter_over_socket
|
counter_over_socket
|
||||||
echo ""
|
echo ""
|
||||||
counter_over_grpc
|
counter_over_grpc
|
||||||
|
echo ""
|
||||||
|
counter_over_grpc_grpc
|
||||||
esac
|
esac
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user