Merge pull request #20 from lbryio/feature/6/jeffreypicard/hub-federation
Most of federation is written, need to finish udp and test
This commit is contained in:
commit
284f825d22
16 changed files with 2047 additions and 497 deletions
5
.github/workflows/build-short.yml
vendored
5
.github/workflows/build-short.yml
vendored
|
@ -1,4 +1,4 @@
|
|||
name: 'Build Hub'
|
||||
name: 'Build and Test Hub'
|
||||
|
||||
on:
|
||||
push:
|
||||
|
@ -10,4 +10,5 @@ jobs:
|
|||
- uses: actions/setup-go@v2.1.3
|
||||
with:
|
||||
go-version: 1.16.5
|
||||
- run: go build .
|
||||
- run: go build .
|
||||
- run: cd server && go test -v -race
|
3
.github/workflows/build.yml
vendored
3
.github/workflows/build.yml
vendored
|
@ -1,4 +1,4 @@
|
|||
name: 'Build Hub'
|
||||
name: 'Build and Test Hub'
|
||||
|
||||
on:
|
||||
push:
|
||||
|
@ -30,3 +30,4 @@ jobs:
|
|||
- run: go get github.com/golang/protobuf/protoc-gen-go google.golang.org/grpc/cmd/protoc-gen-go-grpc
|
||||
- run: go build .
|
||||
- run: ./protobuf/build.sh
|
||||
- run: cd server && go test -v -race
|
||||
|
|
3
go.mod
3
go.mod
|
@ -8,10 +8,11 @@ require (
|
|||
github.com/lbryio/lbry.go/v2 v2.7.2-0.20210625145058-2b155597bf57
|
||||
github.com/olivere/elastic/v7 v7.0.24
|
||||
github.com/prometheus/client_golang v1.11.0
|
||||
github.com/prometheus/client_model v0.2.0
|
||||
golang.org/x/net v0.0.0-20210525063256-abc453219eb5 // indirect
|
||||
golang.org/x/text v0.3.6
|
||||
google.golang.org/genproto v0.0.0-20210524171403-669157292da3 // indirect
|
||||
google.golang.org/grpc v1.38.0
|
||||
google.golang.org/protobuf v1.26.0
|
||||
google.golang.org/protobuf v1.27.1
|
||||
gopkg.in/karalabe/cookiejar.v1 v1.0.0-20141109175019-e1490cae028c
|
||||
)
|
||||
|
|
3
go.sum
3
go.sum
|
@ -313,8 +313,9 @@ google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2
|
|||
google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
|
||||
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
|
||||
google.golang.org/protobuf v1.26.0 h1:bxAC2xTBsZGibn2RTntX0oH50xLsqy1OxA9tTL3p/lk=
|
||||
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
||||
google.golang.org/protobuf v1.27.1 h1:SnqbnDw1V7RiZcXPx5MEeqPv2s79L9i7BJUlG/+RurQ=
|
||||
google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
||||
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
|
|
|
@ -22,5 +22,13 @@ var (
|
|||
Help: "Histogram of query times",
|
||||
Buckets: HistogramBuckets,
|
||||
}, []string{"method"})
|
||||
PeersKnown = promauto.NewGauge(prometheus.GaugeOpts{
|
||||
Name: "peers_known",
|
||||
Help: "Number of peers we know about.",
|
||||
})
|
||||
PeersSubscribed = promauto.NewGauge(prometheus.GaugeOpts{
|
||||
Name: "peers_subbed",
|
||||
Help: "Number of peers that are subscribed to us.",
|
||||
})
|
||||
)
|
||||
|
||||
|
|
192
main.go
192
main.go
|
@ -4,189 +4,45 @@ import (
|
|||
"context"
|
||||
"fmt"
|
||||
"log"
|
||||
"net"
|
||||
"os"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/akamensky/argparse"
|
||||
pb "github.com/lbryio/hub/protobuf/go"
|
||||
"github.com/lbryio/hub/server"
|
||||
"github.com/lbryio/lbry.go/v2/extras/util"
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/reflection"
|
||||
)
|
||||
|
||||
const (
|
||||
defaultHost = "0.0.0.0"
|
||||
defaultPort = "50051"
|
||||
defaultEsHost = "http://localhost"
|
||||
defaultEsIndex = "claims"
|
||||
defaultEsPort = "9200"
|
||||
defaultRefreshDelta = 5
|
||||
defaultCacheTTL = 5
|
||||
)
|
||||
|
||||
func GetEnvironment(data []string, getkeyval func(item string) (key, val string)) map[string]string {
|
||||
items := make(map[string]string)
|
||||
for _, item := range data {
|
||||
key, val := getkeyval(item)
|
||||
items[key] = val
|
||||
}
|
||||
return items
|
||||
}
|
||||
|
||||
func GetEnvironmentStandard() map[string]string {
|
||||
return GetEnvironment(os.Environ(), func(item string) (key, val string) {
|
||||
splits := strings.Split(item, "=")
|
||||
key = splits[0]
|
||||
val = splits[1]
|
||||
return
|
||||
})
|
||||
}
|
||||
|
||||
/*
|
||||
func makeServeCmd(parser *argparse.Parser) *argparse.Command {
|
||||
serveCmd := parser.NewCommand("serve", "start the hub server")
|
||||
|
||||
host := serveCmd.String("", "rpchost", &argparse.Options{Required: false, Help: "host", Default: defaultHost})
|
||||
port := serveCmd.String("", "rpcport", &argparse.Options{Required: false, Help: "port", Default: defaultPort})
|
||||
esHost := serveCmd.String("", "eshost", &argparse.Options{Required: false, Help: "host", Default: defaultEsHost})
|
||||
esPort := serveCmd.String("", "esport", &argparse.Options{Required: false, Help: "port", Default: defaultEsPort})
|
||||
dev := serveCmd.Flag("", "dev", &argparse.Options{Required: false, Help: "port", Default: false})
|
||||
|
||||
return serveCmd
|
||||
}
|
||||
*/
|
||||
|
||||
func parseArgs(searchRequest *pb.SearchRequest) *server.Args {
|
||||
|
||||
environment := GetEnvironmentStandard()
|
||||
parser := argparse.NewParser("hub", "hub server and client")
|
||||
|
||||
serveCmd := parser.NewCommand("serve", "start the hub server")
|
||||
searchCmd := parser.NewCommand("search", "claim search")
|
||||
debug := parser.Flag("", "debug", &argparse.Options{Required: false, Help: "enable debug logging", Default: false})
|
||||
|
||||
host := parser.String("", "rpchost", &argparse.Options{Required: false, Help: "RPC host", Default: defaultHost})
|
||||
port := parser.String("", "rpcport", &argparse.Options{Required: false, Help: "RPC port", Default: defaultPort})
|
||||
esHost := parser.String("", "eshost", &argparse.Options{Required: false, Help: "elasticsearch host", Default: defaultEsHost})
|
||||
esPort := parser.String("", "esport", &argparse.Options{Required: false, Help: "elasticsearch port", Default: defaultEsPort})
|
||||
esIndex := parser.String("", "esindex", &argparse.Options{Required: false, Help: "elasticsearch index name", Default: defaultEsIndex})
|
||||
refreshDelta := parser.Int("", "refresh-delta", &argparse.Options{Required: false, Help: "elasticsearch index refresh delta in seconds", Default: defaultRefreshDelta})
|
||||
cacheTTL := parser.Int("", "cachettl", &argparse.Options{Required: false, Help: "Cache TTL in minutes", Default: defaultCacheTTL})
|
||||
|
||||
text := parser.String("", "text", &argparse.Options{Required: false, Help: "text query"})
|
||||
name := parser.String("", "name", &argparse.Options{Required: false, Help: "name"})
|
||||
claimType := parser.String("", "claim_type", &argparse.Options{Required: false, Help: "claim_type"})
|
||||
id := parser.String("", "id", &argparse.Options{Required: false, Help: "id"})
|
||||
author := parser.String("", "author", &argparse.Options{Required: false, Help: "author"})
|
||||
title := parser.String("", "title", &argparse.Options{Required: false, Help: "title"})
|
||||
description := parser.String("", "description", &argparse.Options{Required: false, Help: "description"})
|
||||
channelId := parser.String("", "channel_id", &argparse.Options{Required: false, Help: "channel id"})
|
||||
channelIds := parser.StringList("", "channel_ids", &argparse.Options{Required: false, Help: "channel ids"})
|
||||
|
||||
// Now parse the arguments
|
||||
err := parser.Parse(os.Args)
|
||||
if err != nil {
|
||||
log.Fatalln(parser.Usage(err))
|
||||
}
|
||||
|
||||
args := &server.Args{
|
||||
CmdType: server.SearchCmd,
|
||||
Host: *host,
|
||||
Port: ":" + *port,
|
||||
EsHost: *esHost,
|
||||
EsPort: *esPort,
|
||||
EsIndex: *esIndex,
|
||||
Debug: *debug,
|
||||
RefreshDelta: *refreshDelta,
|
||||
CacheTTL: *cacheTTL,
|
||||
}
|
||||
|
||||
if esHost, ok := environment["ELASTIC_HOST"]; ok {
|
||||
args.EsHost = esHost
|
||||
}
|
||||
|
||||
if !strings.HasPrefix(args.EsHost, "http") {
|
||||
args.EsHost = "http://" + args.EsHost
|
||||
}
|
||||
|
||||
if esPort, ok := environment["ELASTIC_PORT"]; ok {
|
||||
args.EsPort = esPort
|
||||
}
|
||||
|
||||
/*
|
||||
Verify no invalid argument combinations
|
||||
*/
|
||||
if len(*channelIds) > 0 && *channelId != "" {
|
||||
log.Fatal("Cannot specify both channel_id and channel_ids")
|
||||
}
|
||||
|
||||
if serveCmd.Happened() {
|
||||
args.CmdType = server.ServeCmd
|
||||
} else if searchCmd.Happened() {
|
||||
args.CmdType = server.SearchCmd
|
||||
}
|
||||
|
||||
if *text != "" {
|
||||
searchRequest.Text = *text
|
||||
}
|
||||
if *name != "" {
|
||||
searchRequest.ClaimName = *name
|
||||
}
|
||||
if *claimType != "" {
|
||||
searchRequest.ClaimType = []string{*claimType}
|
||||
}
|
||||
if *id != "" {
|
||||
searchRequest.ClaimId = &pb.InvertibleField{Invert: false, Value: []string{*id}}
|
||||
}
|
||||
if *author != "" {
|
||||
searchRequest.Author = *author
|
||||
}
|
||||
if *title != "" {
|
||||
searchRequest.Title = *title
|
||||
}
|
||||
if *description != "" {
|
||||
searchRequest.Description = *description
|
||||
}
|
||||
if *channelId != "" {
|
||||
searchRequest.ChannelId = &pb.InvertibleField{Invert: false, Value: []string{*channelId}}
|
||||
}
|
||||
if len(*channelIds) > 0 {
|
||||
searchRequest.ChannelId = &pb.InvertibleField{Invert: false, Value: *channelIds}
|
||||
}
|
||||
|
||||
return args
|
||||
}
|
||||
|
||||
func main() {
|
||||
|
||||
ctx := context.Background()
|
||||
searchRequest := &pb.SearchRequest{}
|
||||
|
||||
args := parseArgs(searchRequest)
|
||||
args := server.ParseArgs(searchRequest)
|
||||
|
||||
if args.CmdType == server.ServeCmd {
|
||||
// This will cancel goroutines with the server finishes.
|
||||
ctxWCancel, cancel := context.WithCancel(ctx)
|
||||
defer cancel()
|
||||
|
||||
l, err := net.Listen("tcp", args.Port)
|
||||
if err != nil {
|
||||
log.Fatalf("failed to listen: %v", err)
|
||||
}
|
||||
|
||||
s := server.MakeHubServer(args)
|
||||
pb.RegisterHubServer(s.GrpcServer, s)
|
||||
reflection.Register(s.GrpcServer)
|
||||
|
||||
log.Printf("listening on %s\n", l.Addr().String())
|
||||
log.Println(s.Args)
|
||||
go s.PromethusEndpoint("2112", "metrics")
|
||||
if err := s.GrpcServer.Serve(l); err != nil {
|
||||
log.Fatalf("failed to serve: %v", err)
|
||||
}
|
||||
s := server.MakeHubServer(ctxWCancel, args)
|
||||
s.Run()
|
||||
//l, err := net.Listen("tcp", ":"+args.Port)
|
||||
//if err != nil {
|
||||
// log.Fatalf("failed to listen: %v", err)
|
||||
//}
|
||||
//
|
||||
//pb.RegisterHubServer(s.GrpcServer, s)
|
||||
//reflection.Register(s.GrpcServer)
|
||||
//
|
||||
//log.Printf("listening on %s\n", l.Addr().String())
|
||||
//log.Println(s.Args)
|
||||
//if err := s.GrpcServer.Serve(l); err != nil {
|
||||
// log.Fatalf("failed to serve: %v", err)
|
||||
//}
|
||||
return
|
||||
}
|
||||
|
||||
conn, err := grpc.Dial("localhost"+args.Port,
|
||||
conn, err := grpc.Dial("localhost:"+args.Port,
|
||||
grpc.WithInsecure(),
|
||||
grpc.WithBlock(),
|
||||
)
|
||||
|
@ -197,13 +53,13 @@ func main() {
|
|||
|
||||
c := pb.NewHubClient(conn)
|
||||
|
||||
ctx, cancel := context.WithTimeout(context.Background(), time.Second)
|
||||
defer cancel()
|
||||
ctxWTimeout, cancelQuery := context.WithTimeout(ctx, time.Second)
|
||||
defer cancelQuery()
|
||||
|
||||
log.Println(args)
|
||||
switch args.CmdType {
|
||||
case server.SearchCmd:
|
||||
r, err := c.Search(ctx, searchRequest)
|
||||
r, err := c.Search(ctxWTimeout, searchRequest)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
|
|
@ -8,6 +8,9 @@ package pb;
|
|||
service Hub {
|
||||
rpc Search (SearchRequest) returns (Outputs) {}
|
||||
rpc Ping (EmptyMessage) returns (StringValue) {}
|
||||
rpc Hello (HelloMessage) returns (HelloMessage) {}
|
||||
rpc AddPeer (ServerMessage) returns (StringValue) {}
|
||||
rpc PeerSubscribe (ServerMessage) returns (StringValue) {}
|
||||
rpc Version (EmptyMessage) returns (StringValue) {}
|
||||
rpc Features (EmptyMessage) returns (StringValue) {}
|
||||
rpc Broadcast(EmptyMessage) returns (UInt32Value) {}
|
||||
|
@ -15,6 +18,17 @@ service Hub {
|
|||
|
||||
message EmptyMessage {}
|
||||
|
||||
message ServerMessage {
|
||||
string address = 1;
|
||||
string port = 2;
|
||||
}
|
||||
|
||||
message HelloMessage {
|
||||
string port = 1;
|
||||
string host = 2;
|
||||
repeated ServerMessage servers = 3;
|
||||
}
|
||||
|
||||
message InvertibleField {
|
||||
bool invert = 1;
|
||||
repeated string value = 2;
|
||||
|
|
|
@ -72,7 +72,7 @@ func (x RangeField_Op) Number() protoreflect.EnumNumber {
|
|||
|
||||
// Deprecated: Use RangeField_Op.Descriptor instead.
|
||||
func (RangeField_Op) EnumDescriptor() ([]byte, []int) {
|
||||
return file_hub_proto_rawDescGZIP(), []int{5, 0}
|
||||
return file_hub_proto_rawDescGZIP(), []int{7, 0}
|
||||
}
|
||||
|
||||
type EmptyMessage struct {
|
||||
|
@ -113,6 +113,124 @@ func (*EmptyMessage) Descriptor() ([]byte, []int) {
|
|||
return file_hub_proto_rawDescGZIP(), []int{0}
|
||||
}
|
||||
|
||||
type ServerMessage struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
Address string `protobuf:"bytes,1,opt,name=address,proto3" json:"address"`
|
||||
Port string `protobuf:"bytes,2,opt,name=port,proto3" json:"port"`
|
||||
}
|
||||
|
||||
func (x *ServerMessage) Reset() {
|
||||
*x = ServerMessage{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_hub_proto_msgTypes[1]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *ServerMessage) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*ServerMessage) ProtoMessage() {}
|
||||
|
||||
func (x *ServerMessage) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_hub_proto_msgTypes[1]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use ServerMessage.ProtoReflect.Descriptor instead.
|
||||
func (*ServerMessage) Descriptor() ([]byte, []int) {
|
||||
return file_hub_proto_rawDescGZIP(), []int{1}
|
||||
}
|
||||
|
||||
func (x *ServerMessage) GetAddress() string {
|
||||
if x != nil {
|
||||
return x.Address
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *ServerMessage) GetPort() string {
|
||||
if x != nil {
|
||||
return x.Port
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
type HelloMessage struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
Port string `protobuf:"bytes,1,opt,name=port,proto3" json:"port"`
|
||||
Host string `protobuf:"bytes,2,opt,name=host,proto3" json:"host"`
|
||||
Servers []*ServerMessage `protobuf:"bytes,3,rep,name=servers,proto3" json:"servers"`
|
||||
}
|
||||
|
||||
func (x *HelloMessage) Reset() {
|
||||
*x = HelloMessage{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_hub_proto_msgTypes[2]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *HelloMessage) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*HelloMessage) ProtoMessage() {}
|
||||
|
||||
func (x *HelloMessage) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_hub_proto_msgTypes[2]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use HelloMessage.ProtoReflect.Descriptor instead.
|
||||
func (*HelloMessage) Descriptor() ([]byte, []int) {
|
||||
return file_hub_proto_rawDescGZIP(), []int{2}
|
||||
}
|
||||
|
||||
func (x *HelloMessage) GetPort() string {
|
||||
if x != nil {
|
||||
return x.Port
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *HelloMessage) GetHost() string {
|
||||
if x != nil {
|
||||
return x.Host
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *HelloMessage) GetServers() []*ServerMessage {
|
||||
if x != nil {
|
||||
return x.Servers
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type InvertibleField struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
|
@ -125,7 +243,7 @@ type InvertibleField struct {
|
|||
func (x *InvertibleField) Reset() {
|
||||
*x = InvertibleField{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_hub_proto_msgTypes[1]
|
||||
mi := &file_hub_proto_msgTypes[3]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
@ -138,7 +256,7 @@ func (x *InvertibleField) String() string {
|
|||
func (*InvertibleField) ProtoMessage() {}
|
||||
|
||||
func (x *InvertibleField) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_hub_proto_msgTypes[1]
|
||||
mi := &file_hub_proto_msgTypes[3]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
|
@ -151,7 +269,7 @@ func (x *InvertibleField) ProtoReflect() protoreflect.Message {
|
|||
|
||||
// Deprecated: Use InvertibleField.ProtoReflect.Descriptor instead.
|
||||
func (*InvertibleField) Descriptor() ([]byte, []int) {
|
||||
return file_hub_proto_rawDescGZIP(), []int{1}
|
||||
return file_hub_proto_rawDescGZIP(), []int{3}
|
||||
}
|
||||
|
||||
func (x *InvertibleField) GetInvert() bool {
|
||||
|
@ -179,7 +297,7 @@ type StringValue struct {
|
|||
func (x *StringValue) Reset() {
|
||||
*x = StringValue{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_hub_proto_msgTypes[2]
|
||||
mi := &file_hub_proto_msgTypes[4]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
@ -192,7 +310,7 @@ func (x *StringValue) String() string {
|
|||
func (*StringValue) ProtoMessage() {}
|
||||
|
||||
func (x *StringValue) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_hub_proto_msgTypes[2]
|
||||
mi := &file_hub_proto_msgTypes[4]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
|
@ -205,7 +323,7 @@ func (x *StringValue) ProtoReflect() protoreflect.Message {
|
|||
|
||||
// Deprecated: Use StringValue.ProtoReflect.Descriptor instead.
|
||||
func (*StringValue) Descriptor() ([]byte, []int) {
|
||||
return file_hub_proto_rawDescGZIP(), []int{2}
|
||||
return file_hub_proto_rawDescGZIP(), []int{4}
|
||||
}
|
||||
|
||||
func (x *StringValue) GetValue() string {
|
||||
|
@ -226,7 +344,7 @@ type BoolValue struct {
|
|||
func (x *BoolValue) Reset() {
|
||||
*x = BoolValue{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_hub_proto_msgTypes[3]
|
||||
mi := &file_hub_proto_msgTypes[5]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
@ -239,7 +357,7 @@ func (x *BoolValue) String() string {
|
|||
func (*BoolValue) ProtoMessage() {}
|
||||
|
||||
func (x *BoolValue) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_hub_proto_msgTypes[3]
|
||||
mi := &file_hub_proto_msgTypes[5]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
|
@ -252,7 +370,7 @@ func (x *BoolValue) ProtoReflect() protoreflect.Message {
|
|||
|
||||
// Deprecated: Use BoolValue.ProtoReflect.Descriptor instead.
|
||||
func (*BoolValue) Descriptor() ([]byte, []int) {
|
||||
return file_hub_proto_rawDescGZIP(), []int{3}
|
||||
return file_hub_proto_rawDescGZIP(), []int{5}
|
||||
}
|
||||
|
||||
func (x *BoolValue) GetValue() bool {
|
||||
|
@ -273,7 +391,7 @@ type UInt32Value struct {
|
|||
func (x *UInt32Value) Reset() {
|
||||
*x = UInt32Value{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_hub_proto_msgTypes[4]
|
||||
mi := &file_hub_proto_msgTypes[6]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
@ -286,7 +404,7 @@ func (x *UInt32Value) String() string {
|
|||
func (*UInt32Value) ProtoMessage() {}
|
||||
|
||||
func (x *UInt32Value) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_hub_proto_msgTypes[4]
|
||||
mi := &file_hub_proto_msgTypes[6]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
|
@ -299,7 +417,7 @@ func (x *UInt32Value) ProtoReflect() protoreflect.Message {
|
|||
|
||||
// Deprecated: Use UInt32Value.ProtoReflect.Descriptor instead.
|
||||
func (*UInt32Value) Descriptor() ([]byte, []int) {
|
||||
return file_hub_proto_rawDescGZIP(), []int{4}
|
||||
return file_hub_proto_rawDescGZIP(), []int{6}
|
||||
}
|
||||
|
||||
func (x *UInt32Value) GetValue() uint32 {
|
||||
|
@ -321,7 +439,7 @@ type RangeField struct {
|
|||
func (x *RangeField) Reset() {
|
||||
*x = RangeField{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_hub_proto_msgTypes[5]
|
||||
mi := &file_hub_proto_msgTypes[7]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
@ -334,7 +452,7 @@ func (x *RangeField) String() string {
|
|||
func (*RangeField) ProtoMessage() {}
|
||||
|
||||
func (x *RangeField) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_hub_proto_msgTypes[5]
|
||||
mi := &file_hub_proto_msgTypes[7]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
|
@ -347,7 +465,7 @@ func (x *RangeField) ProtoReflect() protoreflect.Message {
|
|||
|
||||
// Deprecated: Use RangeField.ProtoReflect.Descriptor instead.
|
||||
func (*RangeField) Descriptor() ([]byte, []int) {
|
||||
return file_hub_proto_rawDescGZIP(), []int{5}
|
||||
return file_hub_proto_rawDescGZIP(), []int{7}
|
||||
}
|
||||
|
||||
func (x *RangeField) GetOp() RangeField_Op {
|
||||
|
@ -429,7 +547,7 @@ type SearchRequest struct {
|
|||
func (x *SearchRequest) Reset() {
|
||||
*x = SearchRequest{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_hub_proto_msgTypes[6]
|
||||
mi := &file_hub_proto_msgTypes[8]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
@ -442,7 +560,7 @@ func (x *SearchRequest) String() string {
|
|||
func (*SearchRequest) ProtoMessage() {}
|
||||
|
||||
func (x *SearchRequest) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_hub_proto_msgTypes[6]
|
||||
mi := &file_hub_proto_msgTypes[8]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
|
@ -455,7 +573,7 @@ func (x *SearchRequest) ProtoReflect() protoreflect.Message {
|
|||
|
||||
// Deprecated: Use SearchRequest.ProtoReflect.Descriptor instead.
|
||||
func (*SearchRequest) Descriptor() ([]byte, []int) {
|
||||
return file_hub_proto_rawDescGZIP(), []int{6}
|
||||
return file_hub_proto_rawDescGZIP(), []int{8}
|
||||
}
|
||||
|
||||
func (x *SearchRequest) GetClaimId() *InvertibleField {
|
||||
|
@ -848,186 +966,206 @@ var File_hub_proto protoreflect.FileDescriptor
|
|||
var file_hub_proto_rawDesc = []byte{
|
||||
0x0a, 0x09, 0x68, 0x75, 0x62, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x02, 0x70, 0x62, 0x1a,
|
||||
0x0c, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x0e, 0x0a,
|
||||
0x0c, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x3f, 0x0a,
|
||||
0x0f, 0x49, 0x6e, 0x76, 0x65, 0x72, 0x74, 0x69, 0x62, 0x6c, 0x65, 0x46, 0x69, 0x65, 0x6c, 0x64,
|
||||
0x12, 0x16, 0x0a, 0x06, 0x69, 0x6e, 0x76, 0x65, 0x72, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08,
|
||||
0x52, 0x06, 0x69, 0x6e, 0x76, 0x65, 0x72, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75,
|
||||
0x65, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x23,
|
||||
0x0a, 0x0b, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x14, 0x0a,
|
||||
0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61,
|
||||
0x6c, 0x75, 0x65, 0x22, 0x21, 0x0a, 0x09, 0x42, 0x6f, 0x6f, 0x6c, 0x56, 0x61, 0x6c, 0x75, 0x65,
|
||||
0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52,
|
||||
0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x23, 0x0a, 0x0b, 0x55, 0x49, 0x6e, 0x74, 0x33, 0x32,
|
||||
0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x01,
|
||||
0x20, 0x01, 0x28, 0x0d, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x75, 0x0a, 0x0a, 0x52,
|
||||
0x61, 0x6e, 0x67, 0x65, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x12, 0x21, 0x0a, 0x02, 0x6f, 0x70, 0x18,
|
||||
0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x11, 0x2e, 0x70, 0x62, 0x2e, 0x52, 0x61, 0x6e, 0x67, 0x65,
|
||||
0x46, 0x69, 0x65, 0x6c, 0x64, 0x2e, 0x4f, 0x70, 0x52, 0x02, 0x6f, 0x70, 0x12, 0x14, 0x0a, 0x05,
|
||||
0x0c, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x3d, 0x0a,
|
||||
0x0d, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x18,
|
||||
0x0a, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52,
|
||||
0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x6f, 0x72, 0x74,
|
||||
0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x70, 0x6f, 0x72, 0x74, 0x22, 0x63, 0x0a, 0x0c,
|
||||
0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x12, 0x0a, 0x04,
|
||||
0x70, 0x6f, 0x72, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x70, 0x6f, 0x72, 0x74,
|
||||
0x12, 0x12, 0x0a, 0x04, 0x68, 0x6f, 0x73, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04,
|
||||
0x68, 0x6f, 0x73, 0x74, 0x12, 0x2b, 0x0a, 0x07, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x73, 0x18,
|
||||
0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x70, 0x62, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x65,
|
||||
0x72, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x07, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72,
|
||||
0x73, 0x22, 0x3f, 0x0a, 0x0f, 0x49, 0x6e, 0x76, 0x65, 0x72, 0x74, 0x69, 0x62, 0x6c, 0x65, 0x46,
|
||||
0x69, 0x65, 0x6c, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x69, 0x6e, 0x76, 0x65, 0x72, 0x74, 0x18, 0x01,
|
||||
0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x69, 0x6e, 0x76, 0x65, 0x72, 0x74, 0x12, 0x14, 0x0a, 0x05,
|
||||
0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c,
|
||||
0x75, 0x65, 0x22, 0x2e, 0x0a, 0x02, 0x4f, 0x70, 0x12, 0x06, 0x0a, 0x02, 0x45, 0x51, 0x10, 0x00,
|
||||
0x12, 0x07, 0x0a, 0x03, 0x4c, 0x54, 0x45, 0x10, 0x01, 0x12, 0x07, 0x0a, 0x03, 0x47, 0x54, 0x45,
|
||||
0x10, 0x02, 0x12, 0x06, 0x0a, 0x02, 0x4c, 0x54, 0x10, 0x03, 0x12, 0x06, 0x0a, 0x02, 0x47, 0x54,
|
||||
0x10, 0x04, 0x22, 0xe0, 0x11, 0x0a, 0x0d, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x52, 0x65, 0x71,
|
||||
0x75, 0x65, 0x73, 0x74, 0x12, 0x2e, 0x0a, 0x08, 0x63, 0x6c, 0x61, 0x69, 0x6d, 0x5f, 0x69, 0x64,
|
||||
0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x70, 0x62, 0x2e, 0x49, 0x6e, 0x76, 0x65,
|
||||
0x72, 0x74, 0x69, 0x62, 0x6c, 0x65, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x52, 0x07, 0x63, 0x6c, 0x61,
|
||||
0x69, 0x6d, 0x49, 0x64, 0x12, 0x32, 0x0a, 0x0a, 0x63, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x5f,
|
||||
0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x70, 0x62, 0x2e, 0x49, 0x6e,
|
||||
0x76, 0x65, 0x72, 0x74, 0x69, 0x62, 0x6c, 0x65, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x52, 0x09, 0x63,
|
||||
0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x49, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x65, 0x78, 0x74,
|
||||
0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x65, 0x78, 0x74, 0x12, 0x14, 0x0a, 0x05,
|
||||
0x6c, 0x69, 0x6d, 0x69, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x05, 0x52, 0x05, 0x6c, 0x69, 0x6d,
|
||||
0x69, 0x74, 0x12, 0x19, 0x0a, 0x08, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x5f, 0x62, 0x79, 0x18, 0x05,
|
||||
0x20, 0x03, 0x28, 0x09, 0x52, 0x07, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x42, 0x79, 0x12, 0x16, 0x0a,
|
||||
0x06, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x06, 0x6f,
|
||||
0x66, 0x66, 0x73, 0x65, 0x74, 0x12, 0x25, 0x0a, 0x0e, 0x69, 0x73, 0x5f, 0x63, 0x6f, 0x6e, 0x74,
|
||||
0x72, 0x6f, 0x6c, 0x6c, 0x69, 0x6e, 0x67, 0x18, 0x07, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0d, 0x69,
|
||||
0x73, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x69, 0x6e, 0x67, 0x12, 0x31, 0x0a, 0x15,
|
||||
0x6c, 0x61, 0x73, 0x74, 0x5f, 0x74, 0x61, 0x6b, 0x65, 0x5f, 0x6f, 0x76, 0x65, 0x72, 0x5f, 0x68,
|
||||
0x65, 0x69, 0x67, 0x68, 0x74, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x12, 0x6c, 0x61, 0x73,
|
||||
0x74, 0x54, 0x61, 0x6b, 0x65, 0x4f, 0x76, 0x65, 0x72, 0x48, 0x65, 0x69, 0x67, 0x68, 0x74, 0x12,
|
||||
0x1d, 0x0a, 0x0a, 0x63, 0x6c, 0x61, 0x69, 0x6d, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x09, 0x20,
|
||||
0x01, 0x28, 0x09, 0x52, 0x09, 0x63, 0x6c, 0x61, 0x69, 0x6d, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x27,
|
||||
0x0a, 0x0f, 0x6e, 0x6f, 0x72, 0x6d, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x64, 0x5f, 0x6e, 0x61, 0x6d,
|
||||
0x65, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x6e, 0x6f, 0x72, 0x6d, 0x61, 0x6c, 0x69,
|
||||
0x7a, 0x65, 0x64, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x2f, 0x0a, 0x0b, 0x74, 0x78, 0x5f, 0x70, 0x6f,
|
||||
0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x70,
|
||||
0x62, 0x2e, 0x52, 0x61, 0x6e, 0x67, 0x65, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x52, 0x0a, 0x74, 0x78,
|
||||
0x50, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x26, 0x0a, 0x06, 0x61, 0x6d, 0x6f, 0x75,
|
||||
0x6e, 0x74, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x70, 0x62, 0x2e, 0x52, 0x61,
|
||||
0x6e, 0x67, 0x65, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x52, 0x06, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74,
|
||||
0x12, 0x2c, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x0d, 0x20,
|
||||
0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x70, 0x62, 0x2e, 0x52, 0x61, 0x6e, 0x67, 0x65, 0x46, 0x69,
|
||||
0x65, 0x6c, 0x64, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x3d,
|
||||
0x0a, 0x12, 0x63, 0x72, 0x65, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x73,
|
||||
0x74, 0x61, 0x6d, 0x70, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x70, 0x62, 0x2e,
|
||||
0x52, 0x61, 0x6e, 0x67, 0x65, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x52, 0x11, 0x63, 0x72, 0x65, 0x61,
|
||||
0x74, 0x69, 0x6f, 0x6e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x26, 0x0a,
|
||||
0x06, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e,
|
||||
0x70, 0x62, 0x2e, 0x52, 0x61, 0x6e, 0x67, 0x65, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x52, 0x06, 0x68,
|
||||
0x65, 0x69, 0x67, 0x68, 0x74, 0x12, 0x37, 0x0a, 0x0f, 0x63, 0x72, 0x65, 0x61, 0x74, 0x69, 0x6f,
|
||||
0x6e, 0x5f, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x18, 0x10, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e,
|
||||
0x2e, 0x70, 0x62, 0x2e, 0x52, 0x61, 0x6e, 0x67, 0x65, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x52, 0x0e,
|
||||
0x63, 0x72, 0x65, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x48, 0x65, 0x69, 0x67, 0x68, 0x74, 0x12, 0x3b,
|
||||
0x0a, 0x11, 0x61, 0x63, 0x74, 0x69, 0x76, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x68, 0x65, 0x69,
|
||||
0x67, 0x68, 0x74, 0x18, 0x11, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x70, 0x62, 0x2e, 0x52,
|
||||
0x61, 0x6e, 0x67, 0x65, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x52, 0x10, 0x61, 0x63, 0x74, 0x69, 0x76,
|
||||
0x61, 0x74, 0x69, 0x6f, 0x6e, 0x48, 0x65, 0x69, 0x67, 0x68, 0x74, 0x12, 0x3b, 0x0a, 0x11, 0x65,
|
||||
0x78, 0x70, 0x69, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74,
|
||||
0x18, 0x12, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x70, 0x62, 0x2e, 0x52, 0x61, 0x6e, 0x67,
|
||||
0x65, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x52, 0x10, 0x65, 0x78, 0x70, 0x69, 0x72, 0x61, 0x74, 0x69,
|
||||
0x6f, 0x6e, 0x48, 0x65, 0x69, 0x67, 0x68, 0x74, 0x12, 0x31, 0x0a, 0x0c, 0x72, 0x65, 0x6c, 0x65,
|
||||
0x61, 0x73, 0x65, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x13, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e,
|
||||
0x2e, 0x70, 0x62, 0x2e, 0x52, 0x61, 0x6e, 0x67, 0x65, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x52, 0x0b,
|
||||
0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x73,
|
||||
0x68, 0x6f, 0x72, 0x74, 0x5f, 0x75, 0x72, 0x6c, 0x18, 0x14, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08,
|
||||
0x73, 0x68, 0x6f, 0x72, 0x74, 0x55, 0x72, 0x6c, 0x12, 0x23, 0x0a, 0x0d, 0x63, 0x61, 0x6e, 0x6f,
|
||||
0x6e, 0x69, 0x63, 0x61, 0x6c, 0x5f, 0x75, 0x72, 0x6c, 0x18, 0x15, 0x20, 0x01, 0x28, 0x09, 0x52,
|
||||
0x0c, 0x63, 0x61, 0x6e, 0x6f, 0x6e, 0x69, 0x63, 0x61, 0x6c, 0x55, 0x72, 0x6c, 0x12, 0x14, 0x0a,
|
||||
0x05, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x18, 0x16, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x74, 0x69,
|
||||
0x74, 0x6c, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x18, 0x17, 0x20,
|
||||
0x01, 0x28, 0x09, 0x52, 0x06, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x12, 0x20, 0x0a, 0x0b, 0x64,
|
||||
0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x18, 0x20, 0x01, 0x28, 0x09,
|
||||
0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1d, 0x0a,
|
||||
0x0a, 0x63, 0x6c, 0x61, 0x69, 0x6d, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x19, 0x20, 0x03, 0x28,
|
||||
0x09, 0x52, 0x09, 0x63, 0x6c, 0x61, 0x69, 0x6d, 0x54, 0x79, 0x70, 0x65, 0x12, 0x31, 0x0a, 0x0c,
|
||||
0x72, 0x65, 0x70, 0x6f, 0x73, 0x74, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x1a, 0x20, 0x01,
|
||||
0x75, 0x65, 0x22, 0x23, 0x0a, 0x0b, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x56, 0x61, 0x6c, 0x75,
|
||||
0x65, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09,
|
||||
0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x21, 0x0a, 0x09, 0x42, 0x6f, 0x6f, 0x6c, 0x56,
|
||||
0x61, 0x6c, 0x75, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x01, 0x20,
|
||||
0x01, 0x28, 0x08, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x23, 0x0a, 0x0b, 0x55, 0x49,
|
||||
0x6e, 0x74, 0x33, 0x32, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c,
|
||||
0x75, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22,
|
||||
0x75, 0x0a, 0x0a, 0x52, 0x61, 0x6e, 0x67, 0x65, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x12, 0x21, 0x0a,
|
||||
0x02, 0x6f, 0x70, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x11, 0x2e, 0x70, 0x62, 0x2e, 0x52,
|
||||
0x61, 0x6e, 0x67, 0x65, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x2e, 0x4f, 0x70, 0x52, 0x02, 0x6f, 0x70,
|
||||
0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52,
|
||||
0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x2e, 0x0a, 0x02, 0x4f, 0x70, 0x12, 0x06, 0x0a, 0x02,
|
||||
0x45, 0x51, 0x10, 0x00, 0x12, 0x07, 0x0a, 0x03, 0x4c, 0x54, 0x45, 0x10, 0x01, 0x12, 0x07, 0x0a,
|
||||
0x03, 0x47, 0x54, 0x45, 0x10, 0x02, 0x12, 0x06, 0x0a, 0x02, 0x4c, 0x54, 0x10, 0x03, 0x12, 0x06,
|
||||
0x0a, 0x02, 0x47, 0x54, 0x10, 0x04, 0x22, 0xe0, 0x11, 0x0a, 0x0d, 0x53, 0x65, 0x61, 0x72, 0x63,
|
||||
0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x2e, 0x0a, 0x08, 0x63, 0x6c, 0x61, 0x69,
|
||||
0x6d, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x70, 0x62, 0x2e,
|
||||
0x49, 0x6e, 0x76, 0x65, 0x72, 0x74, 0x69, 0x62, 0x6c, 0x65, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x52,
|
||||
0x07, 0x63, 0x6c, 0x61, 0x69, 0x6d, 0x49, 0x64, 0x12, 0x32, 0x0a, 0x0a, 0x63, 0x68, 0x61, 0x6e,
|
||||
0x6e, 0x65, 0x6c, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x70,
|
||||
0x62, 0x2e, 0x49, 0x6e, 0x76, 0x65, 0x72, 0x74, 0x69, 0x62, 0x6c, 0x65, 0x46, 0x69, 0x65, 0x6c,
|
||||
0x64, 0x52, 0x09, 0x63, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x49, 0x64, 0x12, 0x12, 0x0a, 0x04,
|
||||
0x74, 0x65, 0x78, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x65, 0x78, 0x74,
|
||||
0x12, 0x14, 0x0a, 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x05, 0x52,
|
||||
0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x12, 0x19, 0x0a, 0x08, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x5f,
|
||||
0x62, 0x79, 0x18, 0x05, 0x20, 0x03, 0x28, 0x09, 0x52, 0x07, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x42,
|
||||
0x79, 0x12, 0x16, 0x0a, 0x06, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28,
|
||||
0x0d, 0x52, 0x06, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x12, 0x25, 0x0a, 0x0e, 0x69, 0x73, 0x5f,
|
||||
0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x69, 0x6e, 0x67, 0x18, 0x07, 0x20, 0x01, 0x28,
|
||||
0x08, 0x52, 0x0d, 0x69, 0x73, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x69, 0x6e, 0x67,
|
||||
0x12, 0x31, 0x0a, 0x15, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x74, 0x61, 0x6b, 0x65, 0x5f, 0x6f, 0x76,
|
||||
0x65, 0x72, 0x5f, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52,
|
||||
0x12, 0x6c, 0x61, 0x73, 0x74, 0x54, 0x61, 0x6b, 0x65, 0x4f, 0x76, 0x65, 0x72, 0x48, 0x65, 0x69,
|
||||
0x67, 0x68, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x63, 0x6c, 0x61, 0x69, 0x6d, 0x5f, 0x6e, 0x61, 0x6d,
|
||||
0x65, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x63, 0x6c, 0x61, 0x69, 0x6d, 0x4e, 0x61,
|
||||
0x6d, 0x65, 0x12, 0x27, 0x0a, 0x0f, 0x6e, 0x6f, 0x72, 0x6d, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x64,
|
||||
0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x6e, 0x6f, 0x72,
|
||||
0x6d, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x64, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x2f, 0x0a, 0x0b, 0x74,
|
||||
0x78, 0x5f, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0b,
|
||||
0x32, 0x0e, 0x2e, 0x70, 0x62, 0x2e, 0x52, 0x61, 0x6e, 0x67, 0x65, 0x46, 0x69, 0x65, 0x6c, 0x64,
|
||||
0x52, 0x0a, 0x74, 0x78, 0x50, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x26, 0x0a, 0x06,
|
||||
0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x70,
|
||||
0x62, 0x2e, 0x52, 0x61, 0x6e, 0x67, 0x65, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x52, 0x06, 0x61, 0x6d,
|
||||
0x6f, 0x75, 0x6e, 0x74, 0x12, 0x2c, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d,
|
||||
0x70, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x70, 0x62, 0x2e, 0x52, 0x61, 0x6e,
|
||||
0x67, 0x65, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61,
|
||||
0x6d, 0x70, 0x12, 0x3d, 0x0a, 0x12, 0x63, 0x72, 0x65, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x74,
|
||||
0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e,
|
||||
0x2e, 0x70, 0x62, 0x2e, 0x52, 0x61, 0x6e, 0x67, 0x65, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x52, 0x11,
|
||||
0x63, 0x72, 0x65, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d,
|
||||
0x70, 0x12, 0x26, 0x0a, 0x06, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x18, 0x0f, 0x20, 0x01, 0x28,
|
||||
0x0b, 0x32, 0x0e, 0x2e, 0x70, 0x62, 0x2e, 0x52, 0x61, 0x6e, 0x67, 0x65, 0x46, 0x69, 0x65, 0x6c,
|
||||
0x64, 0x52, 0x06, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x12, 0x37, 0x0a, 0x0f, 0x63, 0x72, 0x65,
|
||||
0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x18, 0x10, 0x20, 0x01,
|
||||
0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x70, 0x62, 0x2e, 0x52, 0x61, 0x6e, 0x67, 0x65, 0x46, 0x69, 0x65,
|
||||
0x6c, 0x64, 0x52, 0x0b, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x74, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12,
|
||||
0x1f, 0x0a, 0x0b, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x1b,
|
||||
0x20, 0x03, 0x28, 0x09, 0x52, 0x0a, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x54, 0x79, 0x70, 0x65,
|
||||
0x12, 0x1d, 0x0a, 0x0a, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x1c,
|
||||
0x20, 0x03, 0x28, 0x09, 0x52, 0x09, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x54, 0x79, 0x70, 0x65, 0x12,
|
||||
0x2d, 0x0a, 0x0a, 0x66, 0x65, 0x65, 0x5f, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x1d, 0x20,
|
||||
0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x70, 0x62, 0x2e, 0x52, 0x61, 0x6e, 0x67, 0x65, 0x46, 0x69,
|
||||
0x65, 0x6c, 0x64, 0x52, 0x09, 0x66, 0x65, 0x65, 0x41, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x21,
|
||||
0x0a, 0x0c, 0x66, 0x65, 0x65, 0x5f, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x63, 0x79, 0x18, 0x1e,
|
||||
0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x66, 0x65, 0x65, 0x43, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x63,
|
||||
0x79, 0x12, 0x2a, 0x0a, 0x08, 0x64, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x1f, 0x20,
|
||||
0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x70, 0x62, 0x2e, 0x52, 0x61, 0x6e, 0x67, 0x65, 0x46, 0x69,
|
||||
0x65, 0x6c, 0x64, 0x52, 0x08, 0x64, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x2a, 0x0a,
|
||||
0x11, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x74, 0x65, 0x64, 0x5f, 0x63, 0x6c, 0x61, 0x69, 0x6d, 0x5f,
|
||||
0x69, 0x64, 0x18, 0x20, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x74,
|
||||
0x65, 0x64, 0x43, 0x6c, 0x61, 0x69, 0x6d, 0x49, 0x64, 0x12, 0x2f, 0x0a, 0x0b, 0x63, 0x65, 0x6e,
|
||||
0x73, 0x6f, 0x72, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x21, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e,
|
||||
0x2e, 0x70, 0x62, 0x2e, 0x52, 0x61, 0x6e, 0x67, 0x65, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x52, 0x0a,
|
||||
0x63, 0x65, 0x6e, 0x73, 0x6f, 0x72, 0x54, 0x79, 0x70, 0x65, 0x12, 0x2a, 0x0a, 0x11, 0x63, 0x6c,
|
||||
0x61, 0x69, 0x6d, 0x73, 0x5f, 0x69, 0x6e, 0x5f, 0x63, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x18,
|
||||
0x22, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x63, 0x6c, 0x61, 0x69, 0x6d, 0x73, 0x49, 0x6e, 0x43,
|
||||
0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x12, 0x31, 0x0a, 0x0c, 0x63, 0x68, 0x61, 0x6e, 0x6e, 0x65,
|
||||
0x6c, 0x5f, 0x6a, 0x6f, 0x69, 0x6e, 0x18, 0x23, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x70,
|
||||
0x62, 0x2e, 0x52, 0x61, 0x6e, 0x67, 0x65, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x52, 0x0b, 0x63, 0x68,
|
||||
0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x4a, 0x6f, 0x69, 0x6e, 0x12, 0x3b, 0x0a, 0x12, 0x69, 0x73, 0x5f,
|
||||
0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x5f, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x18,
|
||||
0x24, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x70, 0x62, 0x2e, 0x42, 0x6f, 0x6f, 0x6c, 0x56,
|
||||
0x61, 0x6c, 0x75, 0x65, 0x52, 0x10, 0x69, 0x73, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72,
|
||||
0x65, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x12, 0x39, 0x0a, 0x10, 0x65, 0x66, 0x66, 0x65, 0x63, 0x74,
|
||||
0x69, 0x76, 0x65, 0x5f, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x25, 0x20, 0x01, 0x28, 0x0b,
|
||||
0x6c, 0x64, 0x52, 0x0e, 0x63, 0x72, 0x65, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x48, 0x65, 0x69, 0x67,
|
||||
0x68, 0x74, 0x12, 0x3b, 0x0a, 0x11, 0x61, 0x63, 0x74, 0x69, 0x76, 0x61, 0x74, 0x69, 0x6f, 0x6e,
|
||||
0x5f, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x18, 0x11, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e,
|
||||
0x70, 0x62, 0x2e, 0x52, 0x61, 0x6e, 0x67, 0x65, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x52, 0x10, 0x61,
|
||||
0x63, 0x74, 0x69, 0x76, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x48, 0x65, 0x69, 0x67, 0x68, 0x74, 0x12,
|
||||
0x3b, 0x0a, 0x11, 0x65, 0x78, 0x70, 0x69, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x68, 0x65,
|
||||
0x69, 0x67, 0x68, 0x74, 0x18, 0x12, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x70, 0x62, 0x2e,
|
||||
0x52, 0x61, 0x6e, 0x67, 0x65, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x52, 0x10, 0x65, 0x78, 0x70, 0x69,
|
||||
0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x48, 0x65, 0x69, 0x67, 0x68, 0x74, 0x12, 0x31, 0x0a, 0x0c,
|
||||
0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x13, 0x20, 0x01,
|
||||
0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x70, 0x62, 0x2e, 0x52, 0x61, 0x6e, 0x67, 0x65, 0x46, 0x69, 0x65,
|
||||
0x6c, 0x64, 0x52, 0x0b, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x12,
|
||||
0x1b, 0x0a, 0x09, 0x73, 0x68, 0x6f, 0x72, 0x74, 0x5f, 0x75, 0x72, 0x6c, 0x18, 0x14, 0x20, 0x01,
|
||||
0x28, 0x09, 0x52, 0x08, 0x73, 0x68, 0x6f, 0x72, 0x74, 0x55, 0x72, 0x6c, 0x12, 0x23, 0x0a, 0x0d,
|
||||
0x63, 0x61, 0x6e, 0x6f, 0x6e, 0x69, 0x63, 0x61, 0x6c, 0x5f, 0x75, 0x72, 0x6c, 0x18, 0x15, 0x20,
|
||||
0x01, 0x28, 0x09, 0x52, 0x0c, 0x63, 0x61, 0x6e, 0x6f, 0x6e, 0x69, 0x63, 0x61, 0x6c, 0x55, 0x72,
|
||||
0x6c, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x18, 0x16, 0x20, 0x01, 0x28, 0x09,
|
||||
0x52, 0x05, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x61, 0x75, 0x74, 0x68, 0x6f,
|
||||
0x72, 0x18, 0x17, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x12,
|
||||
0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x18,
|
||||
0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f,
|
||||
0x6e, 0x12, 0x1d, 0x0a, 0x0a, 0x63, 0x6c, 0x61, 0x69, 0x6d, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18,
|
||||
0x19, 0x20, 0x03, 0x28, 0x09, 0x52, 0x09, 0x63, 0x6c, 0x61, 0x69, 0x6d, 0x54, 0x79, 0x70, 0x65,
|
||||
0x12, 0x31, 0x0a, 0x0c, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x74, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74,
|
||||
0x18, 0x1a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x70, 0x62, 0x2e, 0x52, 0x61, 0x6e, 0x67,
|
||||
0x65, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x52, 0x0b, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x74, 0x43, 0x6f,
|
||||
0x75, 0x6e, 0x74, 0x12, 0x1f, 0x0a, 0x0b, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x5f, 0x74, 0x79,
|
||||
0x70, 0x65, 0x18, 0x1b, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0a, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d,
|
||||
0x54, 0x79, 0x70, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x5f, 0x74, 0x79,
|
||||
0x70, 0x65, 0x18, 0x1c, 0x20, 0x03, 0x28, 0x09, 0x52, 0x09, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x54,
|
||||
0x79, 0x70, 0x65, 0x12, 0x2d, 0x0a, 0x0a, 0x66, 0x65, 0x65, 0x5f, 0x61, 0x6d, 0x6f, 0x75, 0x6e,
|
||||
0x74, 0x18, 0x1d, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x70, 0x62, 0x2e, 0x52, 0x61, 0x6e,
|
||||
0x67, 0x65, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x52, 0x09, 0x66, 0x65, 0x65, 0x41, 0x6d, 0x6f, 0x75,
|
||||
0x6e, 0x74, 0x12, 0x21, 0x0a, 0x0c, 0x66, 0x65, 0x65, 0x5f, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e,
|
||||
0x63, 0x79, 0x18, 0x1e, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x66, 0x65, 0x65, 0x43, 0x75, 0x72,
|
||||
0x72, 0x65, 0x6e, 0x63, 0x79, 0x12, 0x2a, 0x0a, 0x08, 0x64, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f,
|
||||
0x6e, 0x18, 0x1f, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x70, 0x62, 0x2e, 0x52, 0x61, 0x6e,
|
||||
0x67, 0x65, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x52, 0x08, 0x64, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f,
|
||||
0x6e, 0x12, 0x2a, 0x0a, 0x11, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x74, 0x65, 0x64, 0x5f, 0x63, 0x6c,
|
||||
0x61, 0x69, 0x6d, 0x5f, 0x69, 0x64, 0x18, 0x20, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x72, 0x65,
|
||||
0x70, 0x6f, 0x73, 0x74, 0x65, 0x64, 0x43, 0x6c, 0x61, 0x69, 0x6d, 0x49, 0x64, 0x12, 0x2f, 0x0a,
|
||||
0x0b, 0x63, 0x65, 0x6e, 0x73, 0x6f, 0x72, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x21, 0x20, 0x01,
|
||||
0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x70, 0x62, 0x2e, 0x52, 0x61, 0x6e, 0x67, 0x65, 0x46, 0x69, 0x65,
|
||||
0x6c, 0x64, 0x52, 0x0a, 0x63, 0x65, 0x6e, 0x73, 0x6f, 0x72, 0x54, 0x79, 0x70, 0x65, 0x12, 0x2a,
|
||||
0x0a, 0x11, 0x63, 0x6c, 0x61, 0x69, 0x6d, 0x73, 0x5f, 0x69, 0x6e, 0x5f, 0x63, 0x68, 0x61, 0x6e,
|
||||
0x6e, 0x65, 0x6c, 0x18, 0x22, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x63, 0x6c, 0x61, 0x69, 0x6d,
|
||||
0x73, 0x49, 0x6e, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x12, 0x31, 0x0a, 0x0c, 0x63, 0x68,
|
||||
0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x5f, 0x6a, 0x6f, 0x69, 0x6e, 0x18, 0x23, 0x20, 0x01, 0x28, 0x0b,
|
||||
0x32, 0x0e, 0x2e, 0x70, 0x62, 0x2e, 0x52, 0x61, 0x6e, 0x67, 0x65, 0x46, 0x69, 0x65, 0x6c, 0x64,
|
||||
0x52, 0x0f, 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x41, 0x6d, 0x6f, 0x75, 0x6e,
|
||||
0x74, 0x12, 0x35, 0x0a, 0x0e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x5f, 0x61, 0x6d, 0x6f,
|
||||
0x75, 0x6e, 0x74, 0x18, 0x26, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x70, 0x62, 0x2e, 0x52,
|
||||
0x61, 0x6e, 0x67, 0x65, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x52, 0x0d, 0x73, 0x75, 0x70, 0x70, 0x6f,
|
||||
0x72, 0x74, 0x41, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x35, 0x0a, 0x0e, 0x74, 0x72, 0x65, 0x6e,
|
||||
0x64, 0x69, 0x6e, 0x67, 0x5f, 0x73, 0x63, 0x6f, 0x72, 0x65, 0x18, 0x27, 0x20, 0x01, 0x28, 0x0b,
|
||||
0x32, 0x0e, 0x2e, 0x70, 0x62, 0x2e, 0x52, 0x61, 0x6e, 0x67, 0x65, 0x46, 0x69, 0x65, 0x6c, 0x64,
|
||||
0x52, 0x0d, 0x74, 0x72, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x53, 0x63, 0x6f, 0x72, 0x65, 0x12,
|
||||
0x13, 0x0a, 0x05, 0x74, 0x78, 0x5f, 0x69, 0x64, 0x18, 0x2b, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04,
|
||||
0x74, 0x78, 0x49, 0x64, 0x12, 0x28, 0x0a, 0x07, 0x74, 0x78, 0x5f, 0x6e, 0x6f, 0x75, 0x74, 0x18,
|
||||
0x2c, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x70, 0x62, 0x2e, 0x55, 0x49, 0x6e, 0x74, 0x33,
|
||||
0x32, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x06, 0x74, 0x78, 0x4e, 0x6f, 0x75, 0x74, 0x12, 0x1c,
|
||||
0x0a, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x18, 0x2d, 0x20, 0x01, 0x28,
|
||||
0x09, 0x52, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x12, 0x29, 0x0a, 0x10,
|
||||
0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x5f, 0x64, 0x69, 0x67, 0x65, 0x73, 0x74,
|
||||
0x18, 0x2e, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72,
|
||||
0x65, 0x44, 0x69, 0x67, 0x65, 0x73, 0x74, 0x12, 0x28, 0x0a, 0x10, 0x70, 0x75, 0x62, 0x6c, 0x69,
|
||||
0x63, 0x5f, 0x6b, 0x65, 0x79, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, 0x2f, 0x20, 0x01, 0x28,
|
||||
0x09, 0x52, 0x0e, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x42, 0x79, 0x74, 0x65,
|
||||
0x73, 0x12, 0x22, 0x0a, 0x0d, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x5f, 0x6b, 0x65, 0x79, 0x5f,
|
||||
0x69, 0x64, 0x18, 0x30, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63,
|
||||
0x4b, 0x65, 0x79, 0x49, 0x64, 0x12, 0x19, 0x0a, 0x08, 0x61, 0x6e, 0x79, 0x5f, 0x74, 0x61, 0x67,
|
||||
0x73, 0x18, 0x31, 0x20, 0x03, 0x28, 0x09, 0x52, 0x07, 0x61, 0x6e, 0x79, 0x54, 0x61, 0x67, 0x73,
|
||||
0x12, 0x19, 0x0a, 0x08, 0x61, 0x6c, 0x6c, 0x5f, 0x74, 0x61, 0x67, 0x73, 0x18, 0x32, 0x20, 0x03,
|
||||
0x28, 0x09, 0x52, 0x07, 0x61, 0x6c, 0x6c, 0x54, 0x61, 0x67, 0x73, 0x12, 0x19, 0x0a, 0x08, 0x6e,
|
||||
0x6f, 0x74, 0x5f, 0x74, 0x61, 0x67, 0x73, 0x18, 0x33, 0x20, 0x03, 0x28, 0x09, 0x52, 0x07, 0x6e,
|
||||
0x6f, 0x74, 0x54, 0x61, 0x67, 0x73, 0x12, 0x32, 0x0a, 0x15, 0x68, 0x61, 0x73, 0x5f, 0x63, 0x68,
|
||||
0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x5f, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x18,
|
||||
0x34, 0x20, 0x01, 0x28, 0x08, 0x52, 0x13, 0x68, 0x61, 0x73, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65,
|
||||
0x6c, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x12, 0x2c, 0x0a, 0x0a, 0x68, 0x61,
|
||||
0x73, 0x5f, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x18, 0x35, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d,
|
||||
0x2e, 0x70, 0x62, 0x2e, 0x42, 0x6f, 0x6f, 0x6c, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x09, 0x68,
|
||||
0x61, 0x73, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x37, 0x0a, 0x18, 0x6c, 0x69, 0x6d, 0x69,
|
||||
0x74, 0x5f, 0x63, 0x6c, 0x61, 0x69, 0x6d, 0x73, 0x5f, 0x70, 0x65, 0x72, 0x5f, 0x63, 0x68, 0x61,
|
||||
0x6e, 0x6e, 0x65, 0x6c, 0x18, 0x36, 0x20, 0x01, 0x28, 0x05, 0x52, 0x15, 0x6c, 0x69, 0x6d, 0x69,
|
||||
0x74, 0x43, 0x6c, 0x61, 0x69, 0x6d, 0x73, 0x50, 0x65, 0x72, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65,
|
||||
0x6c, 0x12, 0x23, 0x0a, 0x0d, 0x61, 0x6e, 0x79, 0x5f, 0x6c, 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67,
|
||||
0x65, 0x73, 0x18, 0x37, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0c, 0x61, 0x6e, 0x79, 0x4c, 0x61, 0x6e,
|
||||
0x67, 0x75, 0x61, 0x67, 0x65, 0x73, 0x12, 0x23, 0x0a, 0x0d, 0x61, 0x6c, 0x6c, 0x5f, 0x6c, 0x61,
|
||||
0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, 0x73, 0x18, 0x38, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0c, 0x61,
|
||||
0x6c, 0x6c, 0x4c, 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, 0x73, 0x12, 0x2b, 0x0a, 0x11, 0x72,
|
||||
0x65, 0x6d, 0x6f, 0x76, 0x65, 0x5f, 0x64, 0x75, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x65, 0x73,
|
||||
0x18, 0x39, 0x20, 0x01, 0x28, 0x08, 0x52, 0x10, 0x72, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x44, 0x75,
|
||||
0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x65, 0x73, 0x12, 0x1b, 0x0a, 0x09, 0x6e, 0x6f, 0x5f, 0x74,
|
||||
0x6f, 0x74, 0x61, 0x6c, 0x73, 0x18, 0x3a, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x6e, 0x6f, 0x54,
|
||||
0x6f, 0x74, 0x61, 0x6c, 0x73, 0x32, 0xf1, 0x01, 0x0a, 0x03, 0x48, 0x75, 0x62, 0x12, 0x2a, 0x0a,
|
||||
0x06, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x12, 0x11, 0x2e, 0x70, 0x62, 0x2e, 0x53, 0x65, 0x61,
|
||||
0x72, 0x63, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x0b, 0x2e, 0x70, 0x62, 0x2e,
|
||||
0x4f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x73, 0x22, 0x00, 0x12, 0x2b, 0x0a, 0x04, 0x50, 0x69, 0x6e,
|
||||
0x67, 0x12, 0x10, 0x2e, 0x70, 0x62, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x4d, 0x65, 0x73, 0x73,
|
||||
0x61, 0x67, 0x65, 0x1a, 0x0f, 0x2e, 0x70, 0x62, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x56,
|
||||
0x61, 0x6c, 0x75, 0x65, 0x22, 0x00, 0x12, 0x2e, 0x0a, 0x07, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f,
|
||||
0x6e, 0x12, 0x10, 0x2e, 0x70, 0x62, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x4d, 0x65, 0x73, 0x73,
|
||||
0x61, 0x67, 0x65, 0x1a, 0x0f, 0x2e, 0x70, 0x62, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x56,
|
||||
0x61, 0x6c, 0x75, 0x65, 0x22, 0x00, 0x12, 0x2f, 0x0a, 0x08, 0x46, 0x65, 0x61, 0x74, 0x75, 0x72,
|
||||
0x65, 0x73, 0x12, 0x10, 0x2e, 0x70, 0x62, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x4d, 0x65, 0x73,
|
||||
0x73, 0x61, 0x67, 0x65, 0x1a, 0x0f, 0x2e, 0x70, 0x62, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67,
|
||||
0x56, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x00, 0x12, 0x30, 0x0a, 0x09, 0x42, 0x72, 0x6f, 0x61, 0x64,
|
||||
0x63, 0x61, 0x73, 0x74, 0x12, 0x10, 0x2e, 0x70, 0x62, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x4d,
|
||||
0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x1a, 0x0f, 0x2e, 0x70, 0x62, 0x2e, 0x55, 0x49, 0x6e, 0x74,
|
||||
0x33, 0x32, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x00, 0x42, 0x26, 0x5a, 0x24, 0x67, 0x69, 0x74,
|
||||
0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6c, 0x62, 0x72, 0x79, 0x69, 0x6f, 0x2f, 0x68,
|
||||
0x75, 0x62, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x67, 0x6f, 0x2f, 0x70,
|
||||
0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||
0x52, 0x0b, 0x63, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x4a, 0x6f, 0x69, 0x6e, 0x12, 0x3b, 0x0a,
|
||||
0x12, 0x69, 0x73, 0x5f, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x5f, 0x76, 0x61,
|
||||
0x6c, 0x69, 0x64, 0x18, 0x24, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x70, 0x62, 0x2e, 0x42,
|
||||
0x6f, 0x6f, 0x6c, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x10, 0x69, 0x73, 0x53, 0x69, 0x67, 0x6e,
|
||||
0x61, 0x74, 0x75, 0x72, 0x65, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x12, 0x39, 0x0a, 0x10, 0x65, 0x66,
|
||||
0x66, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x25,
|
||||
0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x70, 0x62, 0x2e, 0x52, 0x61, 0x6e, 0x67, 0x65, 0x46,
|
||||
0x69, 0x65, 0x6c, 0x64, 0x52, 0x0f, 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x41,
|
||||
0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x35, 0x0a, 0x0e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74,
|
||||
0x5f, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x26, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e,
|
||||
0x70, 0x62, 0x2e, 0x52, 0x61, 0x6e, 0x67, 0x65, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x52, 0x0d, 0x73,
|
||||
0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x41, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x35, 0x0a, 0x0e,
|
||||
0x74, 0x72, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x5f, 0x73, 0x63, 0x6f, 0x72, 0x65, 0x18, 0x27,
|
||||
0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x70, 0x62, 0x2e, 0x52, 0x61, 0x6e, 0x67, 0x65, 0x46,
|
||||
0x69, 0x65, 0x6c, 0x64, 0x52, 0x0d, 0x74, 0x72, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x53, 0x63,
|
||||
0x6f, 0x72, 0x65, 0x12, 0x13, 0x0a, 0x05, 0x74, 0x78, 0x5f, 0x69, 0x64, 0x18, 0x2b, 0x20, 0x01,
|
||||
0x28, 0x09, 0x52, 0x04, 0x74, 0x78, 0x49, 0x64, 0x12, 0x28, 0x0a, 0x07, 0x74, 0x78, 0x5f, 0x6e,
|
||||
0x6f, 0x75, 0x74, 0x18, 0x2c, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x70, 0x62, 0x2e, 0x55,
|
||||
0x49, 0x6e, 0x74, 0x33, 0x32, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x06, 0x74, 0x78, 0x4e, 0x6f,
|
||||
0x75, 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x18,
|
||||
0x2d, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65,
|
||||
0x12, 0x29, 0x0a, 0x10, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x5f, 0x64, 0x69,
|
||||
0x67, 0x65, 0x73, 0x74, 0x18, 0x2e, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x73, 0x69, 0x67, 0x6e,
|
||||
0x61, 0x74, 0x75, 0x72, 0x65, 0x44, 0x69, 0x67, 0x65, 0x73, 0x74, 0x12, 0x28, 0x0a, 0x10, 0x70,
|
||||
0x75, 0x62, 0x6c, 0x69, 0x63, 0x5f, 0x6b, 0x65, 0x79, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18,
|
||||
0x2f, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79,
|
||||
0x42, 0x79, 0x74, 0x65, 0x73, 0x12, 0x22, 0x0a, 0x0d, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x5f,
|
||||
0x6b, 0x65, 0x79, 0x5f, 0x69, 0x64, 0x18, 0x30, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x70, 0x75,
|
||||
0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x49, 0x64, 0x12, 0x19, 0x0a, 0x08, 0x61, 0x6e, 0x79,
|
||||
0x5f, 0x74, 0x61, 0x67, 0x73, 0x18, 0x31, 0x20, 0x03, 0x28, 0x09, 0x52, 0x07, 0x61, 0x6e, 0x79,
|
||||
0x54, 0x61, 0x67, 0x73, 0x12, 0x19, 0x0a, 0x08, 0x61, 0x6c, 0x6c, 0x5f, 0x74, 0x61, 0x67, 0x73,
|
||||
0x18, 0x32, 0x20, 0x03, 0x28, 0x09, 0x52, 0x07, 0x61, 0x6c, 0x6c, 0x54, 0x61, 0x67, 0x73, 0x12,
|
||||
0x19, 0x0a, 0x08, 0x6e, 0x6f, 0x74, 0x5f, 0x74, 0x61, 0x67, 0x73, 0x18, 0x33, 0x20, 0x03, 0x28,
|
||||
0x09, 0x52, 0x07, 0x6e, 0x6f, 0x74, 0x54, 0x61, 0x67, 0x73, 0x12, 0x32, 0x0a, 0x15, 0x68, 0x61,
|
||||
0x73, 0x5f, 0x63, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x5f, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74,
|
||||
0x75, 0x72, 0x65, 0x18, 0x34, 0x20, 0x01, 0x28, 0x08, 0x52, 0x13, 0x68, 0x61, 0x73, 0x43, 0x68,
|
||||
0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x12, 0x2c,
|
||||
0x0a, 0x0a, 0x68, 0x61, 0x73, 0x5f, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x18, 0x35, 0x20, 0x01,
|
||||
0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x70, 0x62, 0x2e, 0x42, 0x6f, 0x6f, 0x6c, 0x56, 0x61, 0x6c, 0x75,
|
||||
0x65, 0x52, 0x09, 0x68, 0x61, 0x73, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x37, 0x0a, 0x18,
|
||||
0x6c, 0x69, 0x6d, 0x69, 0x74, 0x5f, 0x63, 0x6c, 0x61, 0x69, 0x6d, 0x73, 0x5f, 0x70, 0x65, 0x72,
|
||||
0x5f, 0x63, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x18, 0x36, 0x20, 0x01, 0x28, 0x05, 0x52, 0x15,
|
||||
0x6c, 0x69, 0x6d, 0x69, 0x74, 0x43, 0x6c, 0x61, 0x69, 0x6d, 0x73, 0x50, 0x65, 0x72, 0x43, 0x68,
|
||||
0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x12, 0x23, 0x0a, 0x0d, 0x61, 0x6e, 0x79, 0x5f, 0x6c, 0x61, 0x6e,
|
||||
0x67, 0x75, 0x61, 0x67, 0x65, 0x73, 0x18, 0x37, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0c, 0x61, 0x6e,
|
||||
0x79, 0x4c, 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, 0x73, 0x12, 0x23, 0x0a, 0x0d, 0x61, 0x6c,
|
||||
0x6c, 0x5f, 0x6c, 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, 0x73, 0x18, 0x38, 0x20, 0x03, 0x28,
|
||||
0x09, 0x52, 0x0c, 0x61, 0x6c, 0x6c, 0x4c, 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, 0x73, 0x12,
|
||||
0x2b, 0x0a, 0x11, 0x72, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x5f, 0x64, 0x75, 0x70, 0x6c, 0x69, 0x63,
|
||||
0x61, 0x74, 0x65, 0x73, 0x18, 0x39, 0x20, 0x01, 0x28, 0x08, 0x52, 0x10, 0x72, 0x65, 0x6d, 0x6f,
|
||||
0x76, 0x65, 0x44, 0x75, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x65, 0x73, 0x12, 0x1b, 0x0a, 0x09,
|
||||
0x6e, 0x6f, 0x5f, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x73, 0x18, 0x3a, 0x20, 0x01, 0x28, 0x08, 0x52,
|
||||
0x08, 0x6e, 0x6f, 0x54, 0x6f, 0x74, 0x61, 0x6c, 0x73, 0x32, 0x88, 0x03, 0x0a, 0x03, 0x48, 0x75,
|
||||
0x62, 0x12, 0x2a, 0x0a, 0x06, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x12, 0x11, 0x2e, 0x70, 0x62,
|
||||
0x2e, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x0b,
|
||||
0x2e, 0x70, 0x62, 0x2e, 0x4f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x73, 0x22, 0x00, 0x12, 0x2b, 0x0a,
|
||||
0x04, 0x50, 0x69, 0x6e, 0x67, 0x12, 0x10, 0x2e, 0x70, 0x62, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79,
|
||||
0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x1a, 0x0f, 0x2e, 0x70, 0x62, 0x2e, 0x53, 0x74, 0x72,
|
||||
0x69, 0x6e, 0x67, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x00, 0x12, 0x2d, 0x0a, 0x05, 0x48, 0x65,
|
||||
0x6c, 0x6c, 0x6f, 0x12, 0x10, 0x2e, 0x70, 0x62, 0x2e, 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x4d, 0x65,
|
||||
0x73, 0x73, 0x61, 0x67, 0x65, 0x1a, 0x10, 0x2e, 0x70, 0x62, 0x2e, 0x48, 0x65, 0x6c, 0x6c, 0x6f,
|
||||
0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x00, 0x12, 0x2f, 0x0a, 0x07, 0x41, 0x64, 0x64,
|
||||
0x50, 0x65, 0x65, 0x72, 0x12, 0x11, 0x2e, 0x70, 0x62, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72,
|
||||
0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x1a, 0x0f, 0x2e, 0x70, 0x62, 0x2e, 0x53, 0x74, 0x72,
|
||||
0x69, 0x6e, 0x67, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x00, 0x12, 0x35, 0x0a, 0x0d, 0x50, 0x65,
|
||||
0x65, 0x72, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x12, 0x11, 0x2e, 0x70, 0x62,
|
||||
0x2e, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x1a, 0x0f,
|
||||
0x2e, 0x70, 0x62, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x22,
|
||||
0x00, 0x12, 0x2e, 0x0a, 0x07, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x10, 0x2e, 0x70,
|
||||
0x62, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x1a, 0x0f,
|
||||
0x2e, 0x70, 0x62, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x22,
|
||||
0x00, 0x12, 0x2f, 0x0a, 0x08, 0x46, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x12, 0x10, 0x2e,
|
||||
0x70, 0x62, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x1a,
|
||||
0x0f, 0x2e, 0x70, 0x62, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x56, 0x61, 0x6c, 0x75, 0x65,
|
||||
0x22, 0x00, 0x12, 0x30, 0x0a, 0x09, 0x42, 0x72, 0x6f, 0x61, 0x64, 0x63, 0x61, 0x73, 0x74, 0x12,
|
||||
0x10, 0x2e, 0x70, 0x62, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67,
|
||||
0x65, 0x1a, 0x0f, 0x2e, 0x70, 0x62, 0x2e, 0x55, 0x49, 0x6e, 0x74, 0x33, 0x32, 0x56, 0x61, 0x6c,
|
||||
0x75, 0x65, 0x22, 0x00, 0x42, 0x26, 0x5a, 0x24, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63,
|
||||
0x6f, 0x6d, 0x2f, 0x6c, 0x62, 0x72, 0x79, 0x69, 0x6f, 0x2f, 0x68, 0x75, 0x62, 0x2f, 0x70, 0x72,
|
||||
0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x67, 0x6f, 0x2f, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72,
|
||||
0x6f, 0x74, 0x6f, 0x33,
|
||||
}
|
||||
|
||||
var (
|
||||
|
@ -1043,57 +1181,66 @@ func file_hub_proto_rawDescGZIP() []byte {
|
|||
}
|
||||
|
||||
var file_hub_proto_enumTypes = make([]protoimpl.EnumInfo, 1)
|
||||
var file_hub_proto_msgTypes = make([]protoimpl.MessageInfo, 7)
|
||||
var file_hub_proto_msgTypes = make([]protoimpl.MessageInfo, 9)
|
||||
var file_hub_proto_goTypes = []interface{}{
|
||||
(RangeField_Op)(0), // 0: pb.RangeField.Op
|
||||
(*EmptyMessage)(nil), // 1: pb.EmptyMessage
|
||||
(*InvertibleField)(nil), // 2: pb.InvertibleField
|
||||
(*StringValue)(nil), // 3: pb.StringValue
|
||||
(*BoolValue)(nil), // 4: pb.BoolValue
|
||||
(*UInt32Value)(nil), // 5: pb.UInt32Value
|
||||
(*RangeField)(nil), // 6: pb.RangeField
|
||||
(*SearchRequest)(nil), // 7: pb.SearchRequest
|
||||
(*Outputs)(nil), // 8: pb.Outputs
|
||||
(*ServerMessage)(nil), // 2: pb.ServerMessage
|
||||
(*HelloMessage)(nil), // 3: pb.HelloMessage
|
||||
(*InvertibleField)(nil), // 4: pb.InvertibleField
|
||||
(*StringValue)(nil), // 5: pb.StringValue
|
||||
(*BoolValue)(nil), // 6: pb.BoolValue
|
||||
(*UInt32Value)(nil), // 7: pb.UInt32Value
|
||||
(*RangeField)(nil), // 8: pb.RangeField
|
||||
(*SearchRequest)(nil), // 9: pb.SearchRequest
|
||||
(*Outputs)(nil), // 10: pb.Outputs
|
||||
}
|
||||
var file_hub_proto_depIdxs = []int32{
|
||||
0, // 0: pb.RangeField.op:type_name -> pb.RangeField.Op
|
||||
2, // 1: pb.SearchRequest.claim_id:type_name -> pb.InvertibleField
|
||||
2, // 2: pb.SearchRequest.channel_id:type_name -> pb.InvertibleField
|
||||
6, // 3: pb.SearchRequest.tx_position:type_name -> pb.RangeField
|
||||
6, // 4: pb.SearchRequest.amount:type_name -> pb.RangeField
|
||||
6, // 5: pb.SearchRequest.timestamp:type_name -> pb.RangeField
|
||||
6, // 6: pb.SearchRequest.creation_timestamp:type_name -> pb.RangeField
|
||||
6, // 7: pb.SearchRequest.height:type_name -> pb.RangeField
|
||||
6, // 8: pb.SearchRequest.creation_height:type_name -> pb.RangeField
|
||||
6, // 9: pb.SearchRequest.activation_height:type_name -> pb.RangeField
|
||||
6, // 10: pb.SearchRequest.expiration_height:type_name -> pb.RangeField
|
||||
6, // 11: pb.SearchRequest.release_time:type_name -> pb.RangeField
|
||||
6, // 12: pb.SearchRequest.repost_count:type_name -> pb.RangeField
|
||||
6, // 13: pb.SearchRequest.fee_amount:type_name -> pb.RangeField
|
||||
6, // 14: pb.SearchRequest.duration:type_name -> pb.RangeField
|
||||
6, // 15: pb.SearchRequest.censor_type:type_name -> pb.RangeField
|
||||
6, // 16: pb.SearchRequest.channel_join:type_name -> pb.RangeField
|
||||
4, // 17: pb.SearchRequest.is_signature_valid:type_name -> pb.BoolValue
|
||||
6, // 18: pb.SearchRequest.effective_amount:type_name -> pb.RangeField
|
||||
6, // 19: pb.SearchRequest.support_amount:type_name -> pb.RangeField
|
||||
6, // 20: pb.SearchRequest.trending_score:type_name -> pb.RangeField
|
||||
5, // 21: pb.SearchRequest.tx_nout:type_name -> pb.UInt32Value
|
||||
4, // 22: pb.SearchRequest.has_source:type_name -> pb.BoolValue
|
||||
7, // 23: pb.Hub.Search:input_type -> pb.SearchRequest
|
||||
1, // 24: pb.Hub.Ping:input_type -> pb.EmptyMessage
|
||||
1, // 25: pb.Hub.Version:input_type -> pb.EmptyMessage
|
||||
1, // 26: pb.Hub.Features:input_type -> pb.EmptyMessage
|
||||
1, // 27: pb.Hub.Broadcast:input_type -> pb.EmptyMessage
|
||||
8, // 28: pb.Hub.Search:output_type -> pb.Outputs
|
||||
3, // 29: pb.Hub.Ping:output_type -> pb.StringValue
|
||||
3, // 30: pb.Hub.Version:output_type -> pb.StringValue
|
||||
3, // 31: pb.Hub.Features:output_type -> pb.StringValue
|
||||
5, // 32: pb.Hub.Broadcast:output_type -> pb.UInt32Value
|
||||
28, // [28:33] is the sub-list for method output_type
|
||||
23, // [23:28] is the sub-list for method input_type
|
||||
23, // [23:23] is the sub-list for extension type_name
|
||||
23, // [23:23] is the sub-list for extension extendee
|
||||
0, // [0:23] is the sub-list for field type_name
|
||||
2, // 0: pb.HelloMessage.servers:type_name -> pb.ServerMessage
|
||||
0, // 1: pb.RangeField.op:type_name -> pb.RangeField.Op
|
||||
4, // 2: pb.SearchRequest.claim_id:type_name -> pb.InvertibleField
|
||||
4, // 3: pb.SearchRequest.channel_id:type_name -> pb.InvertibleField
|
||||
8, // 4: pb.SearchRequest.tx_position:type_name -> pb.RangeField
|
||||
8, // 5: pb.SearchRequest.amount:type_name -> pb.RangeField
|
||||
8, // 6: pb.SearchRequest.timestamp:type_name -> pb.RangeField
|
||||
8, // 7: pb.SearchRequest.creation_timestamp:type_name -> pb.RangeField
|
||||
8, // 8: pb.SearchRequest.height:type_name -> pb.RangeField
|
||||
8, // 9: pb.SearchRequest.creation_height:type_name -> pb.RangeField
|
||||
8, // 10: pb.SearchRequest.activation_height:type_name -> pb.RangeField
|
||||
8, // 11: pb.SearchRequest.expiration_height:type_name -> pb.RangeField
|
||||
8, // 12: pb.SearchRequest.release_time:type_name -> pb.RangeField
|
||||
8, // 13: pb.SearchRequest.repost_count:type_name -> pb.RangeField
|
||||
8, // 14: pb.SearchRequest.fee_amount:type_name -> pb.RangeField
|
||||
8, // 15: pb.SearchRequest.duration:type_name -> pb.RangeField
|
||||
8, // 16: pb.SearchRequest.censor_type:type_name -> pb.RangeField
|
||||
8, // 17: pb.SearchRequest.channel_join:type_name -> pb.RangeField
|
||||
6, // 18: pb.SearchRequest.is_signature_valid:type_name -> pb.BoolValue
|
||||
8, // 19: pb.SearchRequest.effective_amount:type_name -> pb.RangeField
|
||||
8, // 20: pb.SearchRequest.support_amount:type_name -> pb.RangeField
|
||||
8, // 21: pb.SearchRequest.trending_score:type_name -> pb.RangeField
|
||||
7, // 22: pb.SearchRequest.tx_nout:type_name -> pb.UInt32Value
|
||||
6, // 23: pb.SearchRequest.has_source:type_name -> pb.BoolValue
|
||||
9, // 24: pb.Hub.Search:input_type -> pb.SearchRequest
|
||||
1, // 25: pb.Hub.Ping:input_type -> pb.EmptyMessage
|
||||
3, // 26: pb.Hub.Hello:input_type -> pb.HelloMessage
|
||||
2, // 27: pb.Hub.AddPeer:input_type -> pb.ServerMessage
|
||||
2, // 28: pb.Hub.PeerSubscribe:input_type -> pb.ServerMessage
|
||||
1, // 29: pb.Hub.Version:input_type -> pb.EmptyMessage
|
||||
1, // 30: pb.Hub.Features:input_type -> pb.EmptyMessage
|
||||
1, // 31: pb.Hub.Broadcast:input_type -> pb.EmptyMessage
|
||||
10, // 32: pb.Hub.Search:output_type -> pb.Outputs
|
||||
5, // 33: pb.Hub.Ping:output_type -> pb.StringValue
|
||||
3, // 34: pb.Hub.Hello:output_type -> pb.HelloMessage
|
||||
5, // 35: pb.Hub.AddPeer:output_type -> pb.StringValue
|
||||
5, // 36: pb.Hub.PeerSubscribe:output_type -> pb.StringValue
|
||||
5, // 37: pb.Hub.Version:output_type -> pb.StringValue
|
||||
5, // 38: pb.Hub.Features:output_type -> pb.StringValue
|
||||
7, // 39: pb.Hub.Broadcast:output_type -> pb.UInt32Value
|
||||
32, // [32:40] is the sub-list for method output_type
|
||||
24, // [24:32] is the sub-list for method input_type
|
||||
24, // [24:24] is the sub-list for extension type_name
|
||||
24, // [24:24] is the sub-list for extension extendee
|
||||
0, // [0:24] is the sub-list for field type_name
|
||||
}
|
||||
|
||||
func init() { file_hub_proto_init() }
|
||||
|
@ -1116,7 +1263,7 @@ func file_hub_proto_init() {
|
|||
}
|
||||
}
|
||||
file_hub_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*InvertibleField); i {
|
||||
switch v := v.(*ServerMessage); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
|
@ -1128,7 +1275,7 @@ func file_hub_proto_init() {
|
|||
}
|
||||
}
|
||||
file_hub_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*StringValue); i {
|
||||
switch v := v.(*HelloMessage); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
|
@ -1140,7 +1287,7 @@ func file_hub_proto_init() {
|
|||
}
|
||||
}
|
||||
file_hub_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*BoolValue); i {
|
||||
switch v := v.(*InvertibleField); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
|
@ -1152,7 +1299,7 @@ func file_hub_proto_init() {
|
|||
}
|
||||
}
|
||||
file_hub_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*UInt32Value); i {
|
||||
switch v := v.(*StringValue); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
|
@ -1164,7 +1311,7 @@ func file_hub_proto_init() {
|
|||
}
|
||||
}
|
||||
file_hub_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*RangeField); i {
|
||||
switch v := v.(*BoolValue); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
|
@ -1176,6 +1323,30 @@ func file_hub_proto_init() {
|
|||
}
|
||||
}
|
||||
file_hub_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*UInt32Value); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_hub_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*RangeField); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_hub_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*SearchRequest); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
|
@ -1194,7 +1365,7 @@ func file_hub_proto_init() {
|
|||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
||||
RawDescriptor: file_hub_proto_rawDesc,
|
||||
NumEnums: 1,
|
||||
NumMessages: 7,
|
||||
NumMessages: 9,
|
||||
NumExtensions: 0,
|
||||
NumServices: 1,
|
||||
},
|
||||
|
|
|
@ -20,6 +20,9 @@ const _ = grpc.SupportPackageIsVersion7
|
|||
type HubClient interface {
|
||||
Search(ctx context.Context, in *SearchRequest, opts ...grpc.CallOption) (*Outputs, error)
|
||||
Ping(ctx context.Context, in *EmptyMessage, opts ...grpc.CallOption) (*StringValue, error)
|
||||
Hello(ctx context.Context, in *HelloMessage, opts ...grpc.CallOption) (*HelloMessage, error)
|
||||
AddPeer(ctx context.Context, in *ServerMessage, opts ...grpc.CallOption) (*StringValue, error)
|
||||
PeerSubscribe(ctx context.Context, in *ServerMessage, opts ...grpc.CallOption) (*StringValue, error)
|
||||
Version(ctx context.Context, in *EmptyMessage, opts ...grpc.CallOption) (*StringValue, error)
|
||||
Features(ctx context.Context, in *EmptyMessage, opts ...grpc.CallOption) (*StringValue, error)
|
||||
Broadcast(ctx context.Context, in *EmptyMessage, opts ...grpc.CallOption) (*UInt32Value, error)
|
||||
|
@ -51,6 +54,33 @@ func (c *hubClient) Ping(ctx context.Context, in *EmptyMessage, opts ...grpc.Cal
|
|||
return out, nil
|
||||
}
|
||||
|
||||
func (c *hubClient) Hello(ctx context.Context, in *HelloMessage, opts ...grpc.CallOption) (*HelloMessage, error) {
|
||||
out := new(HelloMessage)
|
||||
err := c.cc.Invoke(ctx, "/pb.Hub/Hello", in, out, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *hubClient) AddPeer(ctx context.Context, in *ServerMessage, opts ...grpc.CallOption) (*StringValue, error) {
|
||||
out := new(StringValue)
|
||||
err := c.cc.Invoke(ctx, "/pb.Hub/AddPeer", in, out, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *hubClient) PeerSubscribe(ctx context.Context, in *ServerMessage, opts ...grpc.CallOption) (*StringValue, error) {
|
||||
out := new(StringValue)
|
||||
err := c.cc.Invoke(ctx, "/pb.Hub/PeerSubscribe", in, out, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *hubClient) Version(ctx context.Context, in *EmptyMessage, opts ...grpc.CallOption) (*StringValue, error) {
|
||||
out := new(StringValue)
|
||||
err := c.cc.Invoke(ctx, "/pb.Hub/Version", in, out, opts...)
|
||||
|
@ -84,6 +114,9 @@ func (c *hubClient) Broadcast(ctx context.Context, in *EmptyMessage, opts ...grp
|
|||
type HubServer interface {
|
||||
Search(context.Context, *SearchRequest) (*Outputs, error)
|
||||
Ping(context.Context, *EmptyMessage) (*StringValue, error)
|
||||
Hello(context.Context, *HelloMessage) (*HelloMessage, error)
|
||||
AddPeer(context.Context, *ServerMessage) (*StringValue, error)
|
||||
PeerSubscribe(context.Context, *ServerMessage) (*StringValue, error)
|
||||
Version(context.Context, *EmptyMessage) (*StringValue, error)
|
||||
Features(context.Context, *EmptyMessage) (*StringValue, error)
|
||||
Broadcast(context.Context, *EmptyMessage) (*UInt32Value, error)
|
||||
|
@ -100,6 +133,15 @@ func (UnimplementedHubServer) Search(context.Context, *SearchRequest) (*Outputs,
|
|||
func (UnimplementedHubServer) Ping(context.Context, *EmptyMessage) (*StringValue, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method Ping not implemented")
|
||||
}
|
||||
func (UnimplementedHubServer) Hello(context.Context, *HelloMessage) (*HelloMessage, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method Hello not implemented")
|
||||
}
|
||||
func (UnimplementedHubServer) AddPeer(context.Context, *ServerMessage) (*StringValue, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method AddPeer not implemented")
|
||||
}
|
||||
func (UnimplementedHubServer) PeerSubscribe(context.Context, *ServerMessage) (*StringValue, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method PeerSubscribe not implemented")
|
||||
}
|
||||
func (UnimplementedHubServer) Version(context.Context, *EmptyMessage) (*StringValue, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method Version not implemented")
|
||||
}
|
||||
|
@ -158,6 +200,60 @@ func _Hub_Ping_Handler(srv interface{}, ctx context.Context, dec func(interface{
|
|||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _Hub_Hello_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(HelloMessage)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(HubServer).Hello(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: "/pb.Hub/Hello",
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(HubServer).Hello(ctx, req.(*HelloMessage))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _Hub_AddPeer_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(ServerMessage)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(HubServer).AddPeer(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: "/pb.Hub/AddPeer",
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(HubServer).AddPeer(ctx, req.(*ServerMessage))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _Hub_PeerSubscribe_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(ServerMessage)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(HubServer).PeerSubscribe(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: "/pb.Hub/PeerSubscribe",
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(HubServer).PeerSubscribe(ctx, req.(*ServerMessage))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _Hub_Version_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(EmptyMessage)
|
||||
if err := dec(in); err != nil {
|
||||
|
@ -227,6 +323,18 @@ var Hub_ServiceDesc = grpc.ServiceDesc{
|
|||
MethodName: "Ping",
|
||||
Handler: _Hub_Ping_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "Hello",
|
||||
Handler: _Hub_Hello_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "AddPeer",
|
||||
Handler: _Hub_AddPeer_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "PeerSubscribe",
|
||||
Handler: _Hub_PeerSubscribe_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "Version",
|
||||
Handler: _Hub_Version_Handler,
|
||||
|
|
|
@ -24,7 +24,11 @@ AREA_RENAME = {
|
|||
|
||||
def build_upload_binary(release: github3.repos.release.Release) -> None:
|
||||
# os.chdir(absolute_path)
|
||||
os.system("go build .")
|
||||
# os.system("go build .")
|
||||
cmd = f'CGO_ENABLED=0 go build -v -ldflags "-X github.com/lbryio/hub/meta.Version={release.name}"'
|
||||
print(cmd)
|
||||
# os.system("go build .")
|
||||
os.system(cmd)
|
||||
with open("./hub", "rb") as f:
|
||||
release.upload_asset("binary", "hub", f)
|
||||
|
||||
|
@ -225,9 +229,11 @@ def release(args):
|
|||
print(body.getvalue())
|
||||
|
||||
if unlabeled:
|
||||
print('The following PRs were skipped and not included in changelog:')
|
||||
for skipped in unlabeled:
|
||||
print(skipped)
|
||||
w('')
|
||||
print('The following PRs were unlabeled and *will* be included in changelog:')
|
||||
for notskipped in unlabeled:
|
||||
print(notskipped)
|
||||
w(notskipped)
|
||||
|
||||
if fixups:
|
||||
print('The following PRs were marked as fixups and not included in changelog:')
|
||||
|
|
201
server/args.go
Normal file
201
server/args.go
Normal file
|
@ -0,0 +1,201 @@
|
|||
package server
|
||||
|
||||
import (
|
||||
"log"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/akamensky/argparse"
|
||||
pb "github.com/lbryio/hub/protobuf/go"
|
||||
)
|
||||
|
||||
const (
|
||||
ServeCmd = iota
|
||||
SearchCmd = iota
|
||||
)
|
||||
|
||||
// Args struct contains the arguments to the hub server.
|
||||
type Args struct {
|
||||
CmdType int
|
||||
Host string
|
||||
Port string
|
||||
UDPPort string
|
||||
EsHost string
|
||||
EsPort string
|
||||
PrometheusPort string
|
||||
EsIndex string
|
||||
RefreshDelta int
|
||||
CacheTTL int
|
||||
PeerFile string
|
||||
Country string
|
||||
DisableEs bool
|
||||
Debug bool
|
||||
LoadPeers bool
|
||||
StartPrometheus bool
|
||||
StartUDP bool
|
||||
WritePeers bool
|
||||
}
|
||||
|
||||
const (
|
||||
DefaultHost = "0.0.0.0"
|
||||
DefaultPort = "50051"
|
||||
DefaultUdpPort = "41119"
|
||||
DefaultEsHost = "http://localhost"
|
||||
DefaultEsIndex = "claims"
|
||||
DefaultEsPort = "9200"
|
||||
DefaultPrometheusPort = "2112"
|
||||
DefaultRefreshDelta = 5
|
||||
DefaultCacheTTL = 5
|
||||
DefaultPeerFile = "peers.txt"
|
||||
DefaultCountry = "US"
|
||||
DefaultLoadPeers = true
|
||||
DefaultStartPrometheus = true
|
||||
DefaultStartUDP = true
|
||||
DefaultWritePeers = true
|
||||
)
|
||||
|
||||
// GetEnvironment takes the environment variables as an array of strings
|
||||
// and a getkeyval function to turn it into a map.
|
||||
func GetEnvironment(data []string, getkeyval func(item string) (key, val string)) map[string]string {
|
||||
items := make(map[string]string)
|
||||
for _, item := range data {
|
||||
key, val := getkeyval(item)
|
||||
items[key] = val
|
||||
}
|
||||
return items
|
||||
}
|
||||
|
||||
// GetEnvironmentStandard gets the environment variables as a map.
|
||||
func GetEnvironmentStandard() map[string]string {
|
||||
return GetEnvironment(os.Environ(), func(item string) (key, val string) {
|
||||
splits := strings.Split(item, "=")
|
||||
key = splits[0]
|
||||
val = splits[1]
|
||||
return
|
||||
})
|
||||
}
|
||||
|
||||
// ParseArgs parses the command line arguments when started the hub server.
|
||||
func ParseArgs(searchRequest *pb.SearchRequest) *Args {
|
||||
|
||||
environment := GetEnvironmentStandard()
|
||||
parser := argparse.NewParser("hub", "hub server and client")
|
||||
|
||||
serveCmd := parser.NewCommand("serve", "start the hub server")
|
||||
searchCmd := parser.NewCommand("search", "claim search")
|
||||
|
||||
host := parser.String("", "rpchost", &argparse.Options{Required: false, Help: "RPC host", Default: DefaultHost})
|
||||
port := parser.String("", "rpcport", &argparse.Options{Required: false, Help: "RPC port", Default: DefaultPort})
|
||||
esHost := parser.String("", "eshost", &argparse.Options{Required: false, Help: "elasticsearch host", Default: DefaultEsHost})
|
||||
esPort := parser.String("", "esport", &argparse.Options{Required: false, Help: "elasticsearch port", Default: DefaultEsPort})
|
||||
udpPort := parser.String("", "uspport", &argparse.Options{Required: false, Help: "udp ping port", Default: DefaultUdpPort})
|
||||
prometheusPort := parser.String("", "prometheus-port", &argparse.Options{Required: false, Help: "prometheus port", Default: DefaultPrometheusPort})
|
||||
esIndex := parser.String("", "esindex", &argparse.Options{Required: false, Help: "elasticsearch index name", Default: DefaultEsIndex})
|
||||
refreshDelta := parser.Int("", "refresh-delta", &argparse.Options{Required: false, Help: "elasticsearch index refresh delta in seconds", Default: DefaultRefreshDelta})
|
||||
cacheTTL := parser.Int("", "cachettl", &argparse.Options{Required: false, Help: "Cache TTL in minutes", Default: DefaultCacheTTL})
|
||||
peerFile := parser.String("", "peerfile", &argparse.Options{Required: false, Help: "Initial peer file for federation", Default: DefaultPeerFile})
|
||||
country := parser.String("", "country", &argparse.Options{Required: false, Help: "Country this node is running in. Default US.", Default: DefaultCountry})
|
||||
|
||||
debug := parser.Flag("", "debug", &argparse.Options{Required: false, Help: "enable debug logging", Default: false})
|
||||
disableEs := parser.Flag("", "disable-es", &argparse.Options{Required: false, Help: "Disable elastic search, for running/testing independently", Default: false})
|
||||
loadPeers := parser.Flag("", "load-peers", &argparse.Options{Required: false, Help: "load peers from disk at startup", Default: DefaultLoadPeers})
|
||||
startPrometheus := parser.Flag("", "start-prometheus", &argparse.Options{Required: false, Help: "Start prometheus server", Default: DefaultStartPrometheus})
|
||||
startUdp := parser.Flag("", "start-udp", &argparse.Options{Required: false, Help: "Start UDP ping server", Default: DefaultStartUDP})
|
||||
writePeers := parser.Flag("", "write-peers", &argparse.Options{Required: false, Help: "Write peer to disk as we learn about them", Default: DefaultWritePeers})
|
||||
|
||||
text := parser.String("", "text", &argparse.Options{Required: false, Help: "text query"})
|
||||
name := parser.String("", "name", &argparse.Options{Required: false, Help: "name"})
|
||||
claimType := parser.String("", "claim_type", &argparse.Options{Required: false, Help: "claim_type"})
|
||||
id := parser.String("", "id", &argparse.Options{Required: false, Help: "id"})
|
||||
author := parser.String("", "author", &argparse.Options{Required: false, Help: "author"})
|
||||
title := parser.String("", "title", &argparse.Options{Required: false, Help: "title"})
|
||||
description := parser.String("", "description", &argparse.Options{Required: false, Help: "description"})
|
||||
channelId := parser.String("", "channel_id", &argparse.Options{Required: false, Help: "channel id"})
|
||||
channelIds := parser.StringList("", "channel_ids", &argparse.Options{Required: false, Help: "channel ids"})
|
||||
|
||||
// Now parse the arguments
|
||||
err := parser.Parse(os.Args)
|
||||
if err != nil {
|
||||
log.Fatalln(parser.Usage(err))
|
||||
}
|
||||
|
||||
args := &Args{
|
||||
CmdType: SearchCmd,
|
||||
Host: *host,
|
||||
Port: *port,
|
||||
EsHost: *esHost,
|
||||
EsPort: *esPort,
|
||||
UDPPort: *udpPort,
|
||||
PrometheusPort: *prometheusPort,
|
||||
EsIndex: *esIndex,
|
||||
RefreshDelta: *refreshDelta,
|
||||
CacheTTL: *cacheTTL,
|
||||
PeerFile: *peerFile,
|
||||
Country: *country,
|
||||
DisableEs: *disableEs,
|
||||
Debug: *debug,
|
||||
LoadPeers: *loadPeers,
|
||||
StartPrometheus: *startPrometheus,
|
||||
StartUDP: *startUdp,
|
||||
WritePeers: *writePeers,
|
||||
}
|
||||
|
||||
if esHost, ok := environment["ELASTIC_HOST"]; ok {
|
||||
args.EsHost = esHost
|
||||
}
|
||||
|
||||
if !strings.HasPrefix(args.EsHost, "http") {
|
||||
args.EsHost = "http://" + args.EsHost
|
||||
}
|
||||
|
||||
if esPort, ok := environment["ELASTIC_PORT"]; ok {
|
||||
args.EsPort = esPort
|
||||
}
|
||||
|
||||
if prometheusPort, ok := environment["GOHUB_PROMETHEUS_PORT"]; ok {
|
||||
args.PrometheusPort = prometheusPort
|
||||
}
|
||||
|
||||
/*
|
||||
Verify no invalid argument combinations
|
||||
*/
|
||||
if len(*channelIds) > 0 && *channelId != "" {
|
||||
log.Fatal("Cannot specify both channel_id and channel_ids")
|
||||
}
|
||||
|
||||
if serveCmd.Happened() {
|
||||
args.CmdType = ServeCmd
|
||||
} else if searchCmd.Happened() {
|
||||
args.CmdType = SearchCmd
|
||||
}
|
||||
|
||||
if *text != "" {
|
||||
searchRequest.Text = *text
|
||||
}
|
||||
if *name != "" {
|
||||
searchRequest.ClaimName = *name
|
||||
}
|
||||
if *claimType != "" {
|
||||
searchRequest.ClaimType = []string{*claimType}
|
||||
}
|
||||
if *id != "" {
|
||||
searchRequest.ClaimId = &pb.InvertibleField{Invert: false, Value: []string{*id}}
|
||||
}
|
||||
if *author != "" {
|
||||
searchRequest.Author = *author
|
||||
}
|
||||
if *title != "" {
|
||||
searchRequest.Title = *title
|
||||
}
|
||||
if *description != "" {
|
||||
searchRequest.Description = *description
|
||||
}
|
||||
if *channelId != "" {
|
||||
searchRequest.ChannelId = &pb.InvertibleField{Invert: false, Value: []string{*channelId}}
|
||||
}
|
||||
if len(*channelIds) > 0 {
|
||||
searchRequest.ChannelId = &pb.InvertibleField{Invert: false, Value: *channelIds}
|
||||
}
|
||||
|
||||
return args
|
||||
}
|
358
server/federation.go
Normal file
358
server/federation.go
Normal file
|
@ -0,0 +1,358 @@
|
|||
package server
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"context"
|
||||
"log"
|
||||
"os"
|
||||
"strings"
|
||||
"sync/atomic"
|
||||
"time"
|
||||
|
||||
"github.com/lbryio/hub/internal/metrics"
|
||||
pb "github.com/lbryio/hub/protobuf/go"
|
||||
"google.golang.org/grpc"
|
||||
)
|
||||
|
||||
// FederatedServer hold relevant information about peers that we known about.
|
||||
type FederatedServer struct {
|
||||
Address string
|
||||
Port string
|
||||
Ts time.Time
|
||||
}
|
||||
|
||||
var (
|
||||
localHosts = map[string]bool{
|
||||
"127.0.0.1": true,
|
||||
"0.0.0.0": true,
|
||||
"localhost": true,
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
// peerKey takes a ServerMessage object and returns the key that for that peer
|
||||
// in our peer table.
|
||||
func peerKey(msg *pb.ServerMessage) string {
|
||||
return msg.Address + ":" + msg.Port
|
||||
}
|
||||
|
||||
// peerKey is a function on a FederatedServer struct to return the key for that
|
||||
// peer is out peer table.
|
||||
func (peer *FederatedServer) peerKey() string {
|
||||
return peer.Address + ":" + peer.Port
|
||||
}
|
||||
|
||||
func (s *Server) incNumPeers() {
|
||||
atomic.AddInt64(s.NumPeerServers, 1)
|
||||
}
|
||||
|
||||
func (s *Server) decNumPeers() {
|
||||
atomic.AddInt64(s.NumPeerServers, -1)
|
||||
}
|
||||
|
||||
func (s *Server) getNumPeers() int64 {
|
||||
return *s.NumPeerServers
|
||||
}
|
||||
|
||||
func (s *Server) incNumSubs() {
|
||||
atomic.AddInt64(s.NumPeerSubs, 1)
|
||||
}
|
||||
|
||||
func (s *Server) decNumSubs() {
|
||||
atomic.AddInt64(s.NumPeerSubs, -1)
|
||||
}
|
||||
|
||||
func (s *Server) getNumSubs() int64 {
|
||||
return *s.NumPeerSubs
|
||||
}
|
||||
|
||||
// loadPeers takes the arguments given to the hub at startup and loads the
|
||||
// previously known peers from disk and verifies their existence before
|
||||
// storing them as known peers. Returns a map of peerKey -> object
|
||||
func (s *Server) loadPeers() error {
|
||||
peerFile := s.Args.PeerFile
|
||||
port := s.Args.Port
|
||||
|
||||
f, err := os.Open(peerFile)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
return err
|
||||
}
|
||||
scanner := bufio.NewScanner(f)
|
||||
scanner.Split(bufio.ScanLines)
|
||||
var text []string
|
||||
for scanner.Scan() {
|
||||
text = append(text, scanner.Text())
|
||||
}
|
||||
err = f.Close()
|
||||
if err != nil {
|
||||
log.Println("peer file failed to close: ", err)
|
||||
}
|
||||
|
||||
for _, line := range text {
|
||||
ipPort := strings.Split(line,":")
|
||||
if len(ipPort) != 2 {
|
||||
log.Println("Malformed entry in peer file")
|
||||
continue
|
||||
}
|
||||
// If the peer is us, skip
|
||||
log.Println(ipPort)
|
||||
if ipPort[1] == port && localHosts[ipPort[0]] {
|
||||
log.Println("Self peer, skipping ...")
|
||||
continue
|
||||
}
|
||||
srvMsg := &pb.ServerMessage{
|
||||
Address: ipPort[0],
|
||||
Port: ipPort[1],
|
||||
}
|
||||
log.Printf("pinging peer %+v\n", srvMsg)
|
||||
err := s.addPeer(srvMsg, true)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
}
|
||||
}
|
||||
|
||||
log.Println("Returning from loadPeers")
|
||||
return nil
|
||||
}
|
||||
|
||||
// subscribeToPeer subscribes us to a peer to we'll get updates about their
|
||||
// known peers.
|
||||
func (s *Server) subscribeToPeer(peer *FederatedServer) error {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), time.Second)
|
||||
defer cancel()
|
||||
|
||||
conn, err := grpc.DialContext(ctx,
|
||||
peer.Address+":"+peer.Port,
|
||||
grpc.WithInsecure(),
|
||||
grpc.WithBlock(),
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer conn.Close()
|
||||
|
||||
msg := &pb.ServerMessage{
|
||||
Address: s.Args.Host,
|
||||
Port: s.Args.Port,
|
||||
}
|
||||
|
||||
c := pb.NewHubClient(conn)
|
||||
|
||||
log.Printf("%s:%s subscribing to %+v\n", s.Args.Host, s.Args.Port, peer)
|
||||
_, err = c.PeerSubscribe(ctx, msg)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
s.Subscribed = true
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// helloPeer takes a peer to say hello to and sends a hello message
|
||||
// containing all the peers we know about and information about us.
|
||||
// This is used to confirm existence of peers on start and let them
|
||||
// know about us. Returns the response from the server on success,
|
||||
// nil otherwise.
|
||||
func (s *Server) helloPeer(server *FederatedServer) (*pb.HelloMessage, error) {
|
||||
log.Println("In helloPeer")
|
||||
ctx, cancel := context.WithTimeout(context.Background(), time.Second)
|
||||
defer cancel()
|
||||
|
||||
conn, err := grpc.DialContext(ctx,
|
||||
server.Address+":"+server.Port,
|
||||
grpc.WithInsecure(),
|
||||
grpc.WithBlock(),
|
||||
)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
return nil, err
|
||||
}
|
||||
defer conn.Close()
|
||||
|
||||
c := pb.NewHubClient(conn)
|
||||
|
||||
msg := &pb.HelloMessage{
|
||||
Port: s.Args.Port,
|
||||
Host: s.Args.Host,
|
||||
Servers: []*pb.ServerMessage{},
|
||||
}
|
||||
|
||||
log.Printf("%s:%s saying hello to %+v\n", s.Args.Host, s.Args.Port, server)
|
||||
res, err := c.Hello(ctx, msg)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
log.Println(res)
|
||||
|
||||
return res, nil
|
||||
}
|
||||
|
||||
// writePeers writes our current known peers to disk.
|
||||
func (s *Server) writePeers() {
|
||||
if !s.Args.WritePeers {
|
||||
return
|
||||
}
|
||||
f, err := os.Create(s.Args.PeerFile)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
return
|
||||
}
|
||||
writer := bufio.NewWriter(f)
|
||||
|
||||
for key, _ := range s.PeerServers {
|
||||
line := key + "\n"
|
||||
_, err := writer.WriteString(line)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
}
|
||||
}
|
||||
|
||||
err = writer.Flush()
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
}
|
||||
err = f.Close()
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
}
|
||||
}
|
||||
|
||||
// notifyPeer takes a peer to notify and a new peer we just learned about
|
||||
// and calls AddPeer on the first.
|
||||
func notifyPeer(peerToNotify *FederatedServer, newPeer *FederatedServer) error {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), time.Second)
|
||||
defer cancel()
|
||||
|
||||
conn, err := grpc.DialContext(ctx,
|
||||
peerToNotify.Address+":"+peerToNotify.Port,
|
||||
grpc.WithInsecure(),
|
||||
grpc.WithBlock(),
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer conn.Close()
|
||||
|
||||
msg := &pb.ServerMessage{
|
||||
Address: newPeer.Address,
|
||||
Port: newPeer.Port,
|
||||
}
|
||||
|
||||
c := pb.NewHubClient(conn)
|
||||
|
||||
_, err = c.AddPeer(ctx, msg)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// notifyPeerSubs takes a new peer server we just learned about and notifies
|
||||
// all the peers that have subscribed to us about it.
|
||||
func (s *Server) notifyPeerSubs(newServer *FederatedServer) {
|
||||
var unsubscribe []string
|
||||
s.PeerSubsMut.RLock()
|
||||
for key, peer := range s.PeerSubs {
|
||||
log.Printf("Notifying peer %s of new node %+v\n", key, newServer)
|
||||
err := notifyPeer(peer, newServer)
|
||||
if err != nil {
|
||||
log.Println("Failed to send data to ", key)
|
||||
log.Println(err)
|
||||
unsubscribe = append(unsubscribe, key)
|
||||
}
|
||||
}
|
||||
s.PeerSubsMut.RUnlock()
|
||||
|
||||
s.PeerSubsMut.Lock()
|
||||
for _, key := range unsubscribe {
|
||||
if _, ok := s.PeerSubs[key]; ok {
|
||||
delete(s.PeerSubs, key)
|
||||
s.decNumSubs()
|
||||
metrics.PeersSubscribed.Dec()
|
||||
}
|
||||
}
|
||||
s.PeerSubsMut.Unlock()
|
||||
}
|
||||
|
||||
// addPeer takes a new peer as a pb.ServerMessage, optionally checks to see
|
||||
// if they're online, and adds them to our list of peer. If we're not currently
|
||||
// subscribed to a peer, it will also subscribe to it.
|
||||
func (s *Server) addPeer(msg *pb.ServerMessage, ping bool) error {
|
||||
if s.Args.Port == msg.Port &&
|
||||
(localHosts[msg.Address] || msg.Address == s.Args.Host) {
|
||||
log.Printf("%s:%s addPeer: Self peer, skipping...\n", s.Args.Host, s.Args.Port)
|
||||
return nil
|
||||
}
|
||||
k := peerKey(msg)
|
||||
newServer := &FederatedServer{
|
||||
Address: msg.Address,
|
||||
Port: msg.Port,
|
||||
Ts: time.Now(),
|
||||
}
|
||||
log.Printf("%s:%s adding peer %+v\n", s.Args.Host, s.Args.Port, msg)
|
||||
if oldServer, loaded := s.PeerServersLoadOrStore(newServer); !loaded {
|
||||
if ping {
|
||||
_, err := s.helloPeer(newServer)
|
||||
if err != nil {
|
||||
s.PeerServersMut.Lock()
|
||||
delete(s.PeerServers, k)
|
||||
s.PeerServersMut.Unlock()
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
s.incNumPeers()
|
||||
metrics.PeersKnown.Inc()
|
||||
s.writePeers()
|
||||
s.notifyPeerSubs(newServer)
|
||||
|
||||
// Subscribe to all our peers for now
|
||||
err := s.subscribeToPeer(newServer)
|
||||
if err != nil {
|
||||
return err
|
||||
} else {
|
||||
s.Subscribed = true
|
||||
}
|
||||
} else {
|
||||
oldServer.Ts = time.Now()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// mergeFederatedServers is an internal convenience function to add a list of
|
||||
// peers.
|
||||
func (s *Server) mergeFederatedServers(servers []*pb.ServerMessage) {
|
||||
for _, srvMsg := range servers {
|
||||
err := s.addPeer(srvMsg, false)
|
||||
// This shouldn't happen because we're not pinging them.
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// makeHelloMessage makes a message for this hub to call the Hello endpoint
|
||||
// on another hub.
|
||||
func (s *Server) makeHelloMessage() *pb.HelloMessage {
|
||||
servers := make([]*pb.ServerMessage, 0, 10)
|
||||
|
||||
s.PeerServersMut.RLock()
|
||||
for _, peer := range s.PeerServers {
|
||||
servers = append(servers, &pb.ServerMessage{
|
||||
Address: peer.Address,
|
||||
Port: peer.Port,
|
||||
})
|
||||
}
|
||||
s.PeerServersMut.RUnlock()
|
||||
|
||||
return &pb.HelloMessage{
|
||||
Port: s.Args.Port,
|
||||
Host: s.Args.Host,
|
||||
Servers: servers,
|
||||
}
|
||||
}
|
427
server/federation_test.go
Normal file
427
server/federation_test.go
Normal file
|
@ -0,0 +1,427 @@
|
|||
package server
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"context"
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/lbryio/hub/internal/metrics"
|
||||
pb "github.com/lbryio/hub/protobuf/go"
|
||||
dto "github.com/prometheus/client_model/go"
|
||||
"google.golang.org/grpc"
|
||||
)
|
||||
|
||||
// lineCountFile takes a fileName and counts the number of lines in it.
|
||||
func lineCountFile(fileName string) int {
|
||||
f, err := os.Open(fileName)
|
||||
defer f.Close()
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
return 0
|
||||
}
|
||||
scanner := bufio.NewScanner(f)
|
||||
scanner.Split(bufio.ScanLines)
|
||||
var lineCount = 0
|
||||
for scanner.Scan() {
|
||||
scanner.Text()
|
||||
lineCount = lineCount + 1
|
||||
}
|
||||
|
||||
return lineCount
|
||||
}
|
||||
|
||||
// removeFile removes a file.
|
||||
func removeFile(fileName string) {
|
||||
err := os.Remove(fileName)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
}
|
||||
}
|
||||
|
||||
func makeDefaultArgs() *Args {
|
||||
args := &Args{
|
||||
CmdType: ServeCmd,
|
||||
Host: DefaultHost,
|
||||
Port: DefaultPort,
|
||||
EsHost: DefaultEsHost,
|
||||
EsPort: DefaultEsPort,
|
||||
UDPPort: DefaultUdpPort,
|
||||
PrometheusPort: DefaultPrometheusPort,
|
||||
EsIndex: DefaultEsIndex,
|
||||
RefreshDelta: DefaultRefreshDelta,
|
||||
CacheTTL: DefaultCacheTTL,
|
||||
PeerFile: DefaultPeerFile,
|
||||
Country: DefaultCountry,
|
||||
DisableEs: true,
|
||||
Debug: true,
|
||||
LoadPeers: false,
|
||||
StartPrometheus: false,
|
||||
StartUDP: false,
|
||||
WritePeers: false,
|
||||
}
|
||||
|
||||
return args
|
||||
}
|
||||
|
||||
// TestAddPeer tests the ability to add peers
|
||||
func TestAddPeer(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
args := makeDefaultArgs()
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
want int
|
||||
} {
|
||||
{
|
||||
name: "Add 10 peers",
|
||||
want: 10,
|
||||
},
|
||||
{
|
||||
name: "Add 10 peers, 1 unique",
|
||||
want: 1,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T){
|
||||
server := MakeHubServer(ctx, args)
|
||||
server.Subscribed = true
|
||||
metrics.PeersKnown.Set(0)
|
||||
|
||||
for i := 0; i < 10; i++ {
|
||||
var msg *pb.ServerMessage
|
||||
if strings.Contains(tt.name, "1 unique") {
|
||||
msg = &pb.ServerMessage{
|
||||
Address: "1.1.1.1",
|
||||
Port: "50051",
|
||||
}
|
||||
} else {
|
||||
x := i + 1
|
||||
msg = &pb.ServerMessage{
|
||||
Address: fmt.Sprintf("%d.%d.%d.%d", x, x, x, x),
|
||||
Port: "50051",
|
||||
}
|
||||
}
|
||||
//log.Printf("Adding peer %+v\n", msg)
|
||||
err := server.addPeer(msg, false)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
}
|
||||
}
|
||||
var m = &dto.Metric{}
|
||||
if err := metrics.PeersKnown.Write(m); err != nil {
|
||||
t.Errorf("Error getting metrics %+v\n", err)
|
||||
}
|
||||
got := int(*m.Gauge.Value)
|
||||
if got != tt.want {
|
||||
t.Errorf("len(server.PeerServers) = %d, want %d\n", got, tt.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// TestPeerWriter tests that peers get written properly
|
||||
func TestPeerWriter(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
args := makeDefaultArgs()
|
||||
args.WritePeers = true
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
want int
|
||||
} {
|
||||
{
|
||||
name: "Add 10 peers",
|
||||
want: 10,
|
||||
},
|
||||
{
|
||||
name: "Add 10 peers, 1 unique",
|
||||
want: 1,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T){
|
||||
server := MakeHubServer(ctx, args)
|
||||
server.Subscribed = true
|
||||
|
||||
for i := 0; i < 10; i++ {
|
||||
var msg *pb.ServerMessage
|
||||
if strings.Contains(tt.name, "1 unique") {
|
||||
msg = &pb.ServerMessage{
|
||||
Address: "1.1.1.1",
|
||||
Port: "50051",
|
||||
}
|
||||
} else {
|
||||
x := i + 1
|
||||
msg = &pb.ServerMessage{
|
||||
Address: fmt.Sprintf("%d.%d.%d.%d", x, x, x, x),
|
||||
Port: "50051",
|
||||
}
|
||||
}
|
||||
//log.Printf("Adding peer %+v\n", msg)
|
||||
err := server.addPeer(msg, false)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
}
|
||||
}
|
||||
//log.Println("Counting lines...")
|
||||
got := lineCountFile(server.Args.PeerFile)
|
||||
if got != tt.want {
|
||||
t.Errorf("lineCountFile(peers.txt) = %d, want %d", got, tt.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
removeFile(args.PeerFile)
|
||||
}
|
||||
|
||||
// TestAddPeerEndpoint tests the ability to add peers
|
||||
func TestAddPeerEndpoint(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
args := makeDefaultArgs()
|
||||
args2 := makeDefaultArgs()
|
||||
args2.Port = "50052"
|
||||
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
wantServerOne int64
|
||||
wantServerTwo int64
|
||||
} {
|
||||
{
|
||||
// outside -> server1.AddPeer(server2, ping=true) : server1 = 1, server2 = 0
|
||||
// server1 -> server2.Hello(server1) : server1 = 1, server2 = 0
|
||||
// server2 -> server2.addPeer(server1, ping=false) : server1 = 1, server2 = 1
|
||||
// server2 -> server1.PeerSubscribe(server2) : server1 = 1, server2 = 1
|
||||
// server1 <- server2.makeHelloMessage() : server1 = 1, server2 = 1
|
||||
// server1.notifyPeer() : server1 = 1, server2 = 1
|
||||
// server1 -> server2.AddPeer(server2) : server1 = 1, server2 = 1
|
||||
// server2 self peer, skipping : server1 = 1, server2 = 1
|
||||
// server1 -> server2.PeerSubscribe(server1) : server1 = 1, server2 = 1
|
||||
name: "Add 1 peer",
|
||||
wantServerOne: 1,
|
||||
wantServerTwo: 1,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T){
|
||||
server := MakeHubServer(ctx, args)
|
||||
server2 := MakeHubServer(ctx, args2)
|
||||
metrics.PeersKnown.Set(0)
|
||||
go server.Run()
|
||||
go server2.Run()
|
||||
//go server.Run()
|
||||
conn, err := grpc.Dial("localhost:"+args.Port,
|
||||
grpc.WithInsecure(),
|
||||
grpc.WithBlock(),
|
||||
)
|
||||
if err != nil {
|
||||
log.Fatalf("did not connect: %v", err)
|
||||
}
|
||||
|
||||
c := pb.NewHubClient(conn)
|
||||
|
||||
msg := &pb.ServerMessage{
|
||||
Address: "0.0.0.0",
|
||||
Port: "50052",
|
||||
}
|
||||
|
||||
_, err = c.AddPeer(context.Background(), msg)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
}
|
||||
|
||||
server.GrpcServer.GracefulStop()
|
||||
server2.GrpcServer.GracefulStop()
|
||||
got1 := server.getNumPeers()
|
||||
got2 := server2.getNumPeers()
|
||||
if got1 != tt.wantServerOne {
|
||||
t.Errorf("len(server.PeerServers) = %d, want %d\n", got1, tt.wantServerOne)
|
||||
}
|
||||
if got2 != tt.wantServerTwo {
|
||||
t.Errorf("len(server2.PeerServers) = %d, want %d\n", got2, tt.wantServerTwo)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// TestAddPeerEndpoint2 tests the ability to add peers
|
||||
func TestAddPeerEndpoint2(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
args := makeDefaultArgs()
|
||||
args2 := makeDefaultArgs()
|
||||
args3 := makeDefaultArgs()
|
||||
args2.Port = "50052"
|
||||
args3.Port = "50053"
|
||||
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
wantServerOne int64
|
||||
wantServerTwo int64
|
||||
wantServerThree int64
|
||||
} {
|
||||
{
|
||||
name: "Add 2 peers",
|
||||
wantServerOne: 2,
|
||||
wantServerTwo: 2,
|
||||
wantServerThree: 2,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T){
|
||||
server := MakeHubServer(ctx, args)
|
||||
server2 := MakeHubServer(ctx, args2)
|
||||
server3 := MakeHubServer(ctx, args3)
|
||||
metrics.PeersKnown.Set(0)
|
||||
go server.Run()
|
||||
go server2.Run()
|
||||
go server3.Run()
|
||||
conn, err := grpc.Dial("localhost:"+args.Port,
|
||||
grpc.WithInsecure(),
|
||||
grpc.WithBlock(),
|
||||
)
|
||||
if err != nil {
|
||||
log.Fatalf("did not connect: %v", err)
|
||||
}
|
||||
|
||||
c := pb.NewHubClient(conn)
|
||||
|
||||
msg := &pb.ServerMessage{
|
||||
Address: "0.0.0.0",
|
||||
Port: "50052",
|
||||
}
|
||||
|
||||
msg2 := &pb.ServerMessage{
|
||||
Address: "0.0.0.0",
|
||||
Port: "50053",
|
||||
}
|
||||
|
||||
_, err = c.AddPeer(context.Background(), msg)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
}
|
||||
_, err = c.AddPeer(context.Background(), msg2)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
}
|
||||
|
||||
server.GrpcServer.GracefulStop()
|
||||
server2.GrpcServer.GracefulStop()
|
||||
server3.GrpcServer.GracefulStop()
|
||||
got1 := server.getNumPeers()
|
||||
got2 := server2.getNumPeers()
|
||||
got3 := server3.getNumPeers()
|
||||
if got1 != tt.wantServerOne {
|
||||
t.Errorf("len(server.PeerServers) = %d, want %d\n", got1, tt.wantServerOne)
|
||||
}
|
||||
if got2 != tt.wantServerTwo {
|
||||
t.Errorf("len(server2.PeerServers) = %d, want %d\n", got2, tt.wantServerTwo)
|
||||
}
|
||||
if got3 != tt.wantServerThree {
|
||||
t.Errorf("len(server3.PeerServers) = %d, want %d\n", got3, tt.wantServerThree)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
// TestAddPeerEndpoint3 tests the ability to add peers
|
||||
func TestAddPeerEndpoint3(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
args := makeDefaultArgs()
|
||||
args2 := makeDefaultArgs()
|
||||
args3 := makeDefaultArgs()
|
||||
args2.Port = "50052"
|
||||
args3.Port = "50053"
|
||||
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
wantServerOne int64
|
||||
wantServerTwo int64
|
||||
wantServerThree int64
|
||||
} {
|
||||
{
|
||||
name: "Add 1 peer to each",
|
||||
wantServerOne: 2,
|
||||
wantServerTwo: 2,
|
||||
wantServerThree: 2,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T){
|
||||
server := MakeHubServer(ctx, args)
|
||||
server2 := MakeHubServer(ctx, args2)
|
||||
server3 := MakeHubServer(ctx, args3)
|
||||
metrics.PeersKnown.Set(0)
|
||||
go server.Run()
|
||||
go server2.Run()
|
||||
go server3.Run()
|
||||
conn, err := grpc.Dial("localhost:"+args.Port,
|
||||
grpc.WithInsecure(),
|
||||
grpc.WithBlock(),
|
||||
)
|
||||
if err != nil {
|
||||
log.Fatalf("did not connect: %v", err)
|
||||
}
|
||||
conn2, err := grpc.Dial("localhost:50052",
|
||||
grpc.WithInsecure(),
|
||||
grpc.WithBlock(),
|
||||
)
|
||||
if err != nil {
|
||||
log.Fatalf("did not connect: %v", err)
|
||||
}
|
||||
|
||||
c := pb.NewHubClient(conn)
|
||||
c2 := pb.NewHubClient(conn2)
|
||||
|
||||
msg := &pb.ServerMessage{
|
||||
Address: "0.0.0.0",
|
||||
Port: "50052",
|
||||
}
|
||||
|
||||
msg2 := &pb.ServerMessage{
|
||||
Address: "0.0.0.0",
|
||||
Port: "50053",
|
||||
}
|
||||
|
||||
_, err = c.AddPeer(context.Background(), msg)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
}
|
||||
_, err = c2.AddPeer(context.Background(), msg2)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
}
|
||||
|
||||
server.GrpcServer.GracefulStop()
|
||||
server2.GrpcServer.GracefulStop()
|
||||
server3.GrpcServer.GracefulStop()
|
||||
got1 := server.getNumPeers()
|
||||
got2 := server2.getNumPeers()
|
||||
got3 := server3.getNumPeers()
|
||||
if got1 != tt.wantServerOne {
|
||||
t.Errorf("len(server.PeerServers) = %d, want %d\n", got1, tt.wantServerOne)
|
||||
}
|
||||
if got2 != tt.wantServerTwo {
|
||||
t.Errorf("len(server2.PeerServers) = %d, want %d\n", got2, tt.wantServerTwo)
|
||||
}
|
||||
if got3 != tt.wantServerThree {
|
||||
t.Errorf("len(server3.PeerServers) = %d, want %d\n", got3, tt.wantServerThree)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
}
|
|
@ -11,8 +11,6 @@ import (
|
|||
"strings"
|
||||
"time"
|
||||
|
||||
//"github.com/lbryio/hub/schema"
|
||||
|
||||
"github.com/lbryio/hub/internal/metrics"
|
||||
pb "github.com/lbryio/hub/protobuf/go"
|
||||
"github.com/lbryio/lbry.go/v2/extras/util"
|
||||
|
@ -24,8 +22,11 @@ import (
|
|||
"gopkg.in/karalabe/cookiejar.v1/collections/deque"
|
||||
)
|
||||
|
||||
// DefaultSearchSize is the default max number of items an
|
||||
// es search will return.
|
||||
const DefaultSearchSize = 1000
|
||||
|
||||
// record is a struct for the response from es.
|
||||
type record struct {
|
||||
Txid string `json:"tx_id"`
|
||||
Nout uint32 `json:"tx_nout"`
|
||||
|
@ -50,11 +51,14 @@ type record struct {
|
|||
ClaimName string `json:"claim_name"`
|
||||
}
|
||||
|
||||
// orderField is struct for specifying ordering of es search results.
|
||||
type orderField struct {
|
||||
Field string
|
||||
IsAsc bool
|
||||
}
|
||||
|
||||
// StrArrToInterface takes an array of strings and returns them as an array of
|
||||
// interfaces.
|
||||
func StrArrToInterface(arr []string) []interface{} {
|
||||
searchVals := make([]interface{}, len(arr))
|
||||
for i := 0; i < len(arr); i++ {
|
||||
|
@ -63,6 +67,9 @@ func StrArrToInterface(arr []string) []interface{} {
|
|||
return searchVals
|
||||
}
|
||||
|
||||
// AddTermsField takes an es bool query, array of string values and a term
|
||||
// name and adds a TermsQuery for that name matching those values to the
|
||||
// bool query.
|
||||
func AddTermsField(q *elastic.BoolQuery, arr []string, name string) *elastic.BoolQuery {
|
||||
if len(arr) == 0 {
|
||||
return q
|
||||
|
@ -71,6 +78,9 @@ func AddTermsField(q *elastic.BoolQuery, arr []string, name string) *elastic.Boo
|
|||
return q.Must(elastic.NewTermsQuery(name, searchVals...))
|
||||
}
|
||||
|
||||
// AddTermField takes an es bool query, a string value and a term name
|
||||
// and adds a TermQuery for that name matching that value to the bool
|
||||
// query.
|
||||
func AddTermField(q *elastic.BoolQuery, value string, name string) *elastic.BoolQuery {
|
||||
if value != "" {
|
||||
return q.Must(elastic.NewTermQuery(name, value))
|
||||
|
@ -78,6 +88,9 @@ func AddTermField(q *elastic.BoolQuery, value string, name string) *elastic.Bool
|
|||
return q
|
||||
}
|
||||
|
||||
// AddIndividualTermFields takes a bool query, an array of string values
|
||||
// a term name, and a bool to invert the query, and adds multiple individual
|
||||
// TermQuerys for that name matching each of the values.
|
||||
func AddIndividualTermFields(q *elastic.BoolQuery, arr []string, name string, invert bool) *elastic.BoolQuery {
|
||||
for _, x := range arr {
|
||||
if invert {
|
||||
|
@ -89,6 +102,8 @@ func AddIndividualTermFields(q *elastic.BoolQuery, arr []string, name string, in
|
|||
return q
|
||||
}
|
||||
|
||||
// AddRangeField takes a bool query, a range field struct and a term name
|
||||
// and adds a term query for that name matching that range field.
|
||||
func AddRangeField(q *elastic.BoolQuery, rq *pb.RangeField, name string) *elastic.BoolQuery {
|
||||
if rq == nil {
|
||||
return q
|
||||
|
@ -112,6 +127,8 @@ func AddRangeField(q *elastic.BoolQuery, rq *pb.RangeField, name string) *elasti
|
|||
}
|
||||
}
|
||||
|
||||
// AddInvertibleField takes a bool query, an invertible field and a term name
|
||||
// and adds a term query for that name matching that invertible field.
|
||||
func AddInvertibleField(q *elastic.BoolQuery, field *pb.InvertibleField, name string) *elastic.BoolQuery {
|
||||
if field == nil {
|
||||
return q
|
||||
|
@ -128,11 +145,16 @@ func AddInvertibleField(q *elastic.BoolQuery, field *pb.InvertibleField, name st
|
|||
}
|
||||
}
|
||||
|
||||
// recordErrorAndDie is for fatal errors. It takes an error, increments the
|
||||
// fatal error metric in prometheus and prints a fatal error message.
|
||||
func (s *Server) recordErrorAndDie(err error) {
|
||||
metrics.ErrorsCounter.With(prometheus.Labels{"error_type": "fatal"}).Inc()
|
||||
log.Fatalln(err)
|
||||
}
|
||||
|
||||
// RoundUpReleaseTime take a bool query, a range query and a term name
|
||||
// and adds a term query for that name (this is for the release time
|
||||
// field) with the value rounded up.
|
||||
func RoundUpReleaseTime(q *elastic.BoolQuery, rq *pb.RangeField, name string) *elastic.BoolQuery {
|
||||
if rq == nil {
|
||||
return q
|
||||
|
@ -170,6 +192,11 @@ func RoundUpReleaseTime(q *elastic.BoolQuery, rq *pb.RangeField, name string) *e
|
|||
// 8) return streams referenced by repost and all channel referenced in extra_txos
|
||||
//*/
|
||||
func (s *Server) Search(ctx context.Context, in *pb.SearchRequest) (*pb.Outputs, error) {
|
||||
if s.Args.DisableEs {
|
||||
log.Println("ElasticSearch disable, return nil to search")
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
metrics.RequestsCount.With(prometheus.Labels{"method": "search"}).Inc()
|
||||
defer func(t time.Time) {
|
||||
delta := time.Since(t).Seconds()
|
||||
|
@ -301,6 +328,7 @@ func (s *Server) Search(ctx context.Context, in *pb.SearchRequest) (*pb.Outputs,
|
|||
}, nil
|
||||
}
|
||||
|
||||
// normalizeTag takes a string and normalizes it for search in es.
|
||||
func (s *Server) normalizeTag(tag string) string {
|
||||
c := cases.Lower(language.English)
|
||||
res := s.MultiSpaceRe.ReplaceAll(
|
||||
|
@ -312,6 +340,7 @@ func (s *Server) normalizeTag(tag string) string {
|
|||
return string(res)
|
||||
}
|
||||
|
||||
// cleanTags takes an array of tags and normalizes them.
|
||||
func (s *Server) cleanTags(tags []string) []string {
|
||||
cleanedTags := make([]string, len(tags))
|
||||
for i, tag := range tags {
|
||||
|
@ -320,6 +349,8 @@ func (s *Server) cleanTags(tags []string) []string {
|
|||
return cleanedTags
|
||||
}
|
||||
|
||||
// searchResultToRecords takes an elastic.SearchResult object and converts
|
||||
// them to internal record structures.
|
||||
func (s *Server) searchResultToRecords(
|
||||
searchResult *elastic.SearchResult) []*record {
|
||||
records := make([]*record, 0, searchResult.TotalHits())
|
||||
|
@ -334,6 +365,9 @@ func (s *Server) searchResultToRecords(
|
|||
return records
|
||||
}
|
||||
|
||||
// postProcessResults takes es search result records and runs our
|
||||
// post processing on them.
|
||||
// TODO: more in depth description.
|
||||
func (s *Server) postProcessResults(
|
||||
ctx context.Context,
|
||||
client *elastic.Client,
|
||||
|
@ -397,6 +431,8 @@ func (s *Server) postProcessResults(
|
|||
return txos, extraTxos, blocked
|
||||
}
|
||||
|
||||
// checkQuery takes a search request and does a sanity check on it for
|
||||
// validity.
|
||||
func (s *Server) checkQuery(in *pb.SearchRequest) error {
|
||||
limit := 2048
|
||||
checks := map[string]bool{
|
||||
|
@ -418,6 +454,8 @@ func (s *Server) checkQuery(in *pb.SearchRequest) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// setPageVars takes a search request and pointers to the local pageSize
|
||||
// and from variables and sets them from the struct.
|
||||
func setPageVars(in *pb.SearchRequest, pageSize *int, from *int) {
|
||||
if in.Limit > 0 {
|
||||
log.Printf("############ limit: %d\n", in.Limit)
|
||||
|
@ -429,6 +467,8 @@ func setPageVars(in *pb.SearchRequest, pageSize *int, from *int) {
|
|||
}
|
||||
}
|
||||
|
||||
// setupEsQuery takes an elastic.BoolQuery, pb.SearchRequest and orderField
|
||||
// and adds the search request terms to the bool query.
|
||||
func (s *Server) setupEsQuery(
|
||||
q *elastic.BoolQuery,
|
||||
in *pb.SearchRequest,
|
||||
|
@ -625,6 +665,8 @@ func (s *Server) setupEsQuery(
|
|||
return q
|
||||
}
|
||||
|
||||
// getUniqueChannels takes the record results from the es search and returns
|
||||
// the unique channels from those records as a list and a map.
|
||||
func (s *Server) getUniqueChannels(records []*record, client *elastic.Client, ctx context.Context, searchIndices []string) ([]*pb.Output, map[string]*pb.Output) {
|
||||
channels := make(map[string]*pb.Output)
|
||||
channelsSet := make(map[string]bool)
|
||||
|
@ -678,6 +720,9 @@ func (s *Server) getUniqueChannels(records []*record, client *elastic.Client, ct
|
|||
return channelTxos, channels
|
||||
}
|
||||
|
||||
// getClaimsForReposts takes the record results from the es query and returns
|
||||
// an array and map of the reposted records as well as an array of those
|
||||
// records.
|
||||
func (s *Server) getClaimsForReposts(ctx context.Context, client *elastic.Client, records []*record, searchIndices []string) ([]*pb.Output, []*record, map[string]*pb.Output) {
|
||||
|
||||
var totalReposted = 0
|
||||
|
@ -731,10 +776,8 @@ func (s *Server) getClaimsForReposts(ctx context.Context, client *elastic.Client
|
|||
return claims, repostedRecords, respostedMap
|
||||
}
|
||||
|
||||
/*
|
||||
Takes a search request and serializes into a string for use as a key into the
|
||||
internal cache for the hub.
|
||||
*/
|
||||
// serializeSearchRequest takes a search request and serializes it into a key
|
||||
// for use in the internal cache for the hub.
|
||||
func (s *Server) serializeSearchRequest(request *pb.SearchRequest) string {
|
||||
// Save the offest / limit and set to zero, cache hits should happen regardless
|
||||
// and they're used in post processing
|
||||
|
@ -754,6 +797,8 @@ func (s *Server) serializeSearchRequest(request *pb.SearchRequest) string {
|
|||
return str
|
||||
}
|
||||
|
||||
// searchAhead takes an array of record results, the pageSize and
|
||||
// perChannelPerPage value and returns the hits for this page.
|
||||
func searchAhead(searchHits []*record, pageSize int, perChannelPerPage int) []*record {
|
||||
finalHits := make([]*record, 0, len(searchHits))
|
||||
var channelCounters map[string]int
|
||||
|
@ -796,6 +841,8 @@ func searchAhead(searchHits []*record, pageSize int, perChannelPerPage int) []*r
|
|||
return finalHits
|
||||
}
|
||||
|
||||
// recordToOutput is a function on a record struct to turn it into a pb.Output
|
||||
// struct.
|
||||
func (r *record) recordToOutput() *pb.Output {
|
||||
return &pb.Output{
|
||||
TxHash: util.TxIdToTxHash(r.Txid),
|
||||
|
@ -822,6 +869,8 @@ func (r *record) recordToOutput() *pb.Output {
|
|||
}
|
||||
}
|
||||
|
||||
// getHitId is a function on the record struct to get the id for the search
|
||||
// hit.
|
||||
func (r *record) getHitId() string {
|
||||
if r.RepostedClaimId != "" {
|
||||
return r.RepostedClaimId
|
||||
|
@ -830,6 +879,7 @@ func (r *record) getHitId() string {
|
|||
}
|
||||
}
|
||||
|
||||
// removeDuplicates takes an array of record results and remove duplicates.
|
||||
func removeDuplicates(searchHits []*record) []*record {
|
||||
dropped := make(map[*record]bool)
|
||||
// claim_id -> (creation_height, hit_id), where hit_id is either reposted claim id or original
|
||||
|
@ -865,6 +915,8 @@ func removeDuplicates(searchHits []*record) []*record {
|
|||
return deduped
|
||||
}
|
||||
|
||||
// removeBlocked takes an array of record results from the es search
|
||||
// and removes blocked records.
|
||||
func removeBlocked(searchHits []*record) ([]*record, []*record, map[string]*pb.Blocked) {
|
||||
newHits := make([]*record, 0, len(searchHits))
|
||||
blockedHits := make([]*record, 0, len(searchHits))
|
||||
|
|
251
server/server.go
251
server/server.go
|
@ -6,9 +6,11 @@ import (
|
|||
"fmt"
|
||||
"hash"
|
||||
"log"
|
||||
"net"
|
||||
"net/http"
|
||||
"os"
|
||||
"regexp"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/ReneKroon/ttlcache/v2"
|
||||
|
@ -19,47 +21,30 @@ import (
|
|||
"github.com/prometheus/client_golang/prometheus"
|
||||
"github.com/prometheus/client_golang/prometheus/promhttp"
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/reflection"
|
||||
)
|
||||
|
||||
type Server struct {
|
||||
GrpcServer *grpc.Server
|
||||
Args *Args
|
||||
MultiSpaceRe *regexp.Regexp
|
||||
WeirdCharsRe *regexp.Regexp
|
||||
EsClient *elastic.Client
|
||||
Servers []*FederatedServer
|
||||
QueryCache *ttlcache.Cache
|
||||
S256 *hash.Hash
|
||||
GrpcServer *grpc.Server
|
||||
Args *Args
|
||||
MultiSpaceRe *regexp.Regexp
|
||||
WeirdCharsRe *regexp.Regexp
|
||||
EsClient *elastic.Client
|
||||
QueryCache *ttlcache.Cache
|
||||
S256 *hash.Hash
|
||||
LastRefreshCheck time.Time
|
||||
RefreshDelta time.Duration
|
||||
NumESRefreshes int64
|
||||
PeerServers map[string]*FederatedServer
|
||||
PeerServersMut sync.RWMutex
|
||||
NumPeerServers *int64
|
||||
PeerSubs map[string]*FederatedServer
|
||||
PeerSubsMut sync.RWMutex
|
||||
NumPeerSubs *int64
|
||||
Subscribed bool
|
||||
pb.UnimplementedHubServer
|
||||
}
|
||||
|
||||
type FederatedServer struct {
|
||||
Address string
|
||||
Port string
|
||||
Ts time.Time
|
||||
Ping int //?
|
||||
}
|
||||
|
||||
const (
|
||||
ServeCmd = iota
|
||||
SearchCmd = iota
|
||||
)
|
||||
|
||||
type Args struct {
|
||||
// TODO Make command types an enum
|
||||
CmdType int
|
||||
Host string
|
||||
Port string
|
||||
EsHost string
|
||||
EsPort string
|
||||
EsIndex string
|
||||
Debug bool
|
||||
RefreshDelta int
|
||||
CacheTTL int
|
||||
}
|
||||
|
||||
func getVersion() string {
|
||||
return meta.Version
|
||||
|
@ -104,7 +89,56 @@ func getVersion() string {
|
|||
'blockchain.address.unsubscribe'
|
||||
*/
|
||||
|
||||
func MakeHubServer(args *Args) *Server {
|
||||
func (s *Server) PeerSubsLoadOrStore(peer *FederatedServer) (actual *FederatedServer, loaded bool) {
|
||||
key := peer.peerKey()
|
||||
s.PeerSubsMut.RLock()
|
||||
if actual, ok := s.PeerSubs[key]; ok {
|
||||
s.PeerSubsMut.RUnlock()
|
||||
return actual, true
|
||||
} else {
|
||||
s.PeerSubsMut.RUnlock()
|
||||
s.PeerSubsMut.Lock()
|
||||
s.PeerSubs[key] = peer
|
||||
s.PeerSubsMut.Unlock()
|
||||
return peer, false
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Server) PeerServersLoadOrStore(peer *FederatedServer) (actual *FederatedServer, loaded bool) {
|
||||
key := peer.peerKey()
|
||||
s.PeerServersMut.RLock()
|
||||
if actual, ok := s.PeerServers[key]; ok {
|
||||
s.PeerServersMut.RUnlock()
|
||||
return actual, true
|
||||
} else {
|
||||
s.PeerServersMut.RUnlock()
|
||||
s.PeerServersMut.Lock()
|
||||
s.PeerServers[key] = peer
|
||||
s.PeerServersMut.Unlock()
|
||||
return peer, false
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Server) Run() {
|
||||
l, err := net.Listen("tcp", ":"+s.Args.Port)
|
||||
if err != nil {
|
||||
log.Fatalf("failed to listen: %v", err)
|
||||
}
|
||||
|
||||
pb.RegisterHubServer(s.GrpcServer, s)
|
||||
reflection.Register(s.GrpcServer)
|
||||
|
||||
log.Printf("listening on %s\n", l.Addr().String())
|
||||
log.Println(s.Args)
|
||||
if err := s.GrpcServer.Serve(l); err != nil {
|
||||
log.Fatalf("failed to serve: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
// MakeHubServer takes the arguments given to a hub when it's started and
|
||||
// initializes everything. It loads information about previously known peers,
|
||||
// creates needed internal data structures, and initializes goroutines.
|
||||
func MakeHubServer(ctx context.Context, args *Args) *Server {
|
||||
grpcServer := grpc.NewServer(grpc.NumStreamWorkers(10))
|
||||
|
||||
multiSpaceRe, err := regexp.Compile(`\s{2,}`)
|
||||
|
@ -116,23 +150,23 @@ func MakeHubServer(args *Args) *Server {
|
|||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
self := &FederatedServer{
|
||||
Address: "127.0.0.1",
|
||||
Port: args.Port,
|
||||
Ts: time.Now(),
|
||||
Ping: 0,
|
||||
}
|
||||
servers := make([]*FederatedServer, 10)
|
||||
servers = append(servers, self)
|
||||
|
||||
esUrl := args.EsHost + ":" + args.EsPort
|
||||
opts := []elastic.ClientOptionFunc{elastic.SetSniff(false), elastic.SetURL(esUrl)}
|
||||
if args.Debug {
|
||||
opts = append(opts, elastic.SetTraceLog(log.New(os.Stderr, "[[ELASTIC]]", 0)))
|
||||
}
|
||||
client, err := elastic.NewClient(opts...)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
var client *elastic.Client = nil
|
||||
if !args.DisableEs {
|
||||
esUrl := args.EsHost + ":" + args.EsPort
|
||||
opts := []elastic.ClientOptionFunc{
|
||||
elastic.SetSniff(true),
|
||||
elastic.SetSnifferTimeoutStartup(time.Second * 60),
|
||||
elastic.SetSnifferTimeout(time.Second * 60),
|
||||
elastic.SetURL(esUrl),
|
||||
}
|
||||
if args.Debug {
|
||||
opts = append(opts, elastic.SetTraceLog(log.New(os.Stderr, "[[ELASTIC]]", 0)))
|
||||
}
|
||||
client, err = elastic.NewClient(opts...)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
cache := ttlcache.NewCache()
|
||||
|
@ -146,45 +180,130 @@ func MakeHubServer(args *Args) *Server {
|
|||
refreshDelta = time.Second * 0
|
||||
}
|
||||
|
||||
numPeers := new(int64)
|
||||
*numPeers = 0
|
||||
numSubs := new(int64)
|
||||
*numSubs = 0
|
||||
|
||||
s := &Server{
|
||||
GrpcServer: grpcServer,
|
||||
Args: args,
|
||||
MultiSpaceRe: multiSpaceRe,
|
||||
WeirdCharsRe: weirdCharsRe,
|
||||
EsClient: client,
|
||||
QueryCache: cache,
|
||||
S256: &s256,
|
||||
Args: args,
|
||||
MultiSpaceRe: multiSpaceRe,
|
||||
WeirdCharsRe: weirdCharsRe,
|
||||
EsClient: client,
|
||||
QueryCache: cache,
|
||||
S256: &s256,
|
||||
LastRefreshCheck: time.Now(),
|
||||
RefreshDelta: refreshDelta,
|
||||
RefreshDelta: refreshDelta,
|
||||
NumESRefreshes: 0,
|
||||
PeerServers: make(map[string]*FederatedServer),
|
||||
PeerServersMut: sync.RWMutex{},
|
||||
NumPeerServers: numPeers,
|
||||
PeerSubs: make(map[string]*FederatedServer),
|
||||
PeerSubsMut: sync.RWMutex{},
|
||||
NumPeerSubs: numSubs,
|
||||
Subscribed: false,
|
||||
}
|
||||
|
||||
// Start up our background services
|
||||
if args.StartPrometheus {
|
||||
go s.prometheusEndpoint(s.Args.PrometheusPort, "metrics")
|
||||
}
|
||||
if args.StartUDP {
|
||||
go func() {
|
||||
err := UDPServer(args)
|
||||
if err != nil {
|
||||
log.Println("UDP Server failed!", err)
|
||||
}
|
||||
}()
|
||||
}
|
||||
// Load peers from disk and subscribe to one if there are any
|
||||
if args.LoadPeers {
|
||||
err = s.loadPeers()
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
}
|
||||
}
|
||||
|
||||
return s
|
||||
}
|
||||
|
||||
func (s *Server) PromethusEndpoint(port string, endpoint string) error {
|
||||
// prometheusEndpoint is a goroutine which start up a prometheus endpoint
|
||||
// for this hub to allow for metric tracking.
|
||||
func (s *Server) prometheusEndpoint(port string, endpoint string) {
|
||||
http.Handle("/"+endpoint, promhttp.Handler())
|
||||
log.Println(fmt.Sprintf("listening on :%s /%s", port, endpoint))
|
||||
err := http.ListenAndServe(":"+port, nil)
|
||||
if err != nil {
|
||||
return err
|
||||
log.Fatalln("Shouldn't happen??!?!", err)
|
||||
}
|
||||
|
||||
// Hello is a grpc endpoint to allow another hub to tell us about itself.
|
||||
// The passed message includes information about the other hub, and all
|
||||
// of its peers which are added to the knowledge of this hub.
|
||||
func (s *Server) Hello(ctx context.Context, args *pb.HelloMessage) (*pb.HelloMessage, error) {
|
||||
metrics.RequestsCount.With(prometheus.Labels{"method": "hello"}).Inc()
|
||||
port := args.Port
|
||||
host := args.Host
|
||||
server := &FederatedServer{
|
||||
Address: host,
|
||||
Port: port,
|
||||
Ts: time.Now(),
|
||||
}
|
||||
log.Fatalln("Shouldn't happen??!?!")
|
||||
return nil
|
||||
log.Println(server)
|
||||
|
||||
err := s.addPeer(&pb.ServerMessage{Address: host, Port: port}, false)
|
||||
// They just contacted us, so this shouldn't happen
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
}
|
||||
s.mergeFederatedServers(args.Servers)
|
||||
s.writePeers()
|
||||
s.notifyPeerSubs(server)
|
||||
|
||||
return s.makeHelloMessage(), nil
|
||||
}
|
||||
|
||||
func (s *Server) Hello(context context.Context, args *FederatedServer) (*FederatedServer, error) {
|
||||
s.Servers = append(s.Servers, args)
|
||||
// PeerSubscribe adds a peer hub to the list of subscribers to update about
|
||||
// new peers.
|
||||
func (s *Server) PeerSubscribe(ctx context.Context, in *pb.ServerMessage) (*pb.StringValue, error) {
|
||||
metrics.RequestsCount.With(prometheus.Labels{"method": "peer_subscribe"}).Inc()
|
||||
var msg = "Success"
|
||||
peer := &FederatedServer{
|
||||
Address: in.Address,
|
||||
Port: in.Port,
|
||||
Ts: time.Now(),
|
||||
}
|
||||
|
||||
return s.Servers[0], nil
|
||||
if _, loaded := s.PeerSubsLoadOrStore(peer); !loaded {
|
||||
s.incNumSubs()
|
||||
metrics.PeersSubscribed.Inc()
|
||||
} else {
|
||||
msg = "Already subscribed"
|
||||
}
|
||||
|
||||
return &pb.StringValue{Value: msg}, nil
|
||||
}
|
||||
|
||||
func (s *Server) Ping(context context.Context, args *pb.EmptyMessage) (*pb.StringValue, error) {
|
||||
// AddPeer is a grpc endpoint to tell this hub about another hub in the network.
|
||||
func (s *Server) AddPeer(ctx context.Context, args *pb.ServerMessage) (*pb.StringValue, error) {
|
||||
metrics.RequestsCount.With(prometheus.Labels{"method": "add_peer"}).Inc()
|
||||
var msg = "Success"
|
||||
err := s.addPeer(args, true)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
msg = "Failed"
|
||||
}
|
||||
return &pb.StringValue{Value: msg}, err
|
||||
}
|
||||
|
||||
// Ping is a grpc endpoint that returns a short message.
|
||||
func (s *Server) Ping(ctx context.Context, args *pb.EmptyMessage) (*pb.StringValue, error) {
|
||||
metrics.RequestsCount.With(prometheus.Labels{"method": "ping"}).Inc()
|
||||
return &pb.StringValue{Value: "Hello, world!"}, nil
|
||||
}
|
||||
|
||||
func (s *Server) Version(context context.Context, args *pb.EmptyMessage) (*pb.StringValue, error) {
|
||||
// Version is a grpc endpoint to get this hub's version.
|
||||
func (s *Server) Version(ctx context.Context, args *pb.EmptyMessage) (*pb.StringValue, error) {
|
||||
metrics.RequestsCount.With(prometheus.Labels{"method": "version"}).Inc()
|
||||
return &pb.StringValue{Value: getVersion()}, nil
|
||||
}
|
||||
|
|
226
server/udp.go
Normal file
226
server/udp.go
Normal file
|
@ -0,0 +1,226 @@
|
|||
package server
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"fmt"
|
||||
"net"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/lbryio/lbry.go/v2/extras/errors"
|
||||
)
|
||||
|
||||
const maxBufferSize = 1024
|
||||
// genesis blocktime (which is actually wrong)
|
||||
const magic = 1446058291
|
||||
const protocolVersion = 1
|
||||
|
||||
// SPVPing is a struct for the format of how to ping another hub over udp.
|
||||
// format b'!lB64s'
|
||||
type SPVPing struct {
|
||||
magic uint32
|
||||
version byte
|
||||
padding []byte //64
|
||||
}
|
||||
|
||||
// SPVPong is a struct for the return pong from another hub server.
|
||||
// format b'!BBL32s4sH'
|
||||
type SPVPong struct {
|
||||
protocolVersion byte
|
||||
flags byte
|
||||
height uint32
|
||||
tip []byte // 32
|
||||
srcAddrRaw []byte // 4
|
||||
country uint16
|
||||
}
|
||||
|
||||
// encodeSPVPing creates a slice of bytes to ping another hub with
|
||||
// over udp.
|
||||
func encodeSPVPing() []byte {
|
||||
data := make([]byte, 69)
|
||||
|
||||
binary.BigEndian.PutUint32(data, magic)
|
||||
data[4] = protocolVersion
|
||||
|
||||
return data
|
||||
}
|
||||
|
||||
// decodeSPVPing takes a slice of bytes and decodes an SPVPing struct from them.
|
||||
func decodeSPVPing(data []byte) *SPVPing {
|
||||
if len(data) < 69 {
|
||||
return nil
|
||||
}
|
||||
|
||||
parsedMagic := binary.BigEndian.Uint32(data)
|
||||
parsedProtocalVersion := data[4]
|
||||
return &SPVPing{
|
||||
magic: parsedMagic,
|
||||
version: parsedProtocalVersion,
|
||||
}
|
||||
}
|
||||
|
||||
// Encode is a function for SPVPong structs to encode them into bytes for
|
||||
// sending over udp.
|
||||
func (pong *SPVPong) Encode() []byte {
|
||||
data := make([]byte, 44)
|
||||
|
||||
data[0] = pong.protocolVersion
|
||||
data[1] = pong.flags
|
||||
binary.BigEndian.PutUint32(data[2:], pong.height)
|
||||
copy(data[6:], pong.tip)
|
||||
copy(data[38:], pong.srcAddrRaw)
|
||||
binary.BigEndian.PutUint16(data[42:], pong.country)
|
||||
|
||||
return data
|
||||
}
|
||||
|
||||
// makeSPVPong creates an SPVPong struct according to given parameters.
|
||||
// FIXME: Currently, does not correctly encode the country.
|
||||
func makeSPVPong(flags int, height int, tip []byte, sourceAddr string, country string) *SPVPong {
|
||||
byteAddr := EncodeAddress(sourceAddr)
|
||||
countryInt := 1
|
||||
return &SPVPong{
|
||||
protocolVersion: protocolVersion,
|
||||
flags: byte(flags),
|
||||
height: uint32(height),
|
||||
tip: tip,
|
||||
srcAddrRaw: byteAddr,
|
||||
country: uint16(countryInt),
|
||||
}
|
||||
}
|
||||
|
||||
// decodeSPVPong takes a slice of bytes and decodes an SPVPong struct
|
||||
// from it.
|
||||
func decodeSPVPong(data []byte) *SPVPong {
|
||||
if len(data) < 44 {
|
||||
return nil
|
||||
}
|
||||
|
||||
parsedProtocalVersion := data[0]
|
||||
flags := data[1]
|
||||
height := binary.BigEndian.Uint32(data[:2])
|
||||
tip := make([]byte, 32)
|
||||
copy(tip, data[6:38])
|
||||
srcRawAddr := make([]byte, 4)
|
||||
copy(srcRawAddr, data[38:42])
|
||||
country := binary.BigEndian.Uint16(data[:42])
|
||||
return &SPVPong{
|
||||
protocolVersion: parsedProtocalVersion,
|
||||
flags: flags,
|
||||
height: height,
|
||||
tip: tip,
|
||||
srcAddrRaw: srcRawAddr,
|
||||
country: country,
|
||||
}
|
||||
}
|
||||
|
||||
// EncodeAddress takes an ipv4 address and encodes it into bytes for the hub
|
||||
// Ping/Pong protocol.
|
||||
func EncodeAddress(addr string) []byte {
|
||||
parts := strings.Split(addr, ".")
|
||||
|
||||
if len(parts) != 4 {
|
||||
return []byte{}
|
||||
}
|
||||
|
||||
data := make([]byte, 4)
|
||||
for i, part := range parts {
|
||||
x, err := strconv.Atoi(part)
|
||||
if err != nil || x > 255 {
|
||||
return []byte{}
|
||||
}
|
||||
data[i] = byte(x)
|
||||
}
|
||||
|
||||
return data
|
||||
}
|
||||
|
||||
// DecodeAddress gets the string ipv4 address from an SPVPong struct.
|
||||
func (pong *SPVPong) DecodeAddress() string {
|
||||
return fmt.Sprintf("%d.%d.%d.%d",
|
||||
pong.srcAddrRaw[0],
|
||||
pong.srcAddrRaw[1],
|
||||
pong.srcAddrRaw[2],
|
||||
pong.srcAddrRaw[3],
|
||||
)
|
||||
}
|
||||
|
||||
// UDPPing sends a ping over udp to another hub and returns the ip address of
|
||||
// this hub.
|
||||
func UDPPing(address string) (string, error) {
|
||||
addr, err := net.ResolveUDPAddr("udp", address)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
conn, err := net.DialUDP("udp", nil, addr)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
defer conn.Close()
|
||||
|
||||
_, err = conn.Write(encodeSPVPing())
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
buffer := make([]byte, maxBufferSize)
|
||||
deadline := time.Now().Add(time.Second)
|
||||
err = conn.SetReadDeadline(deadline)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
n, _, err := conn.ReadFromUDP(buffer)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
pong := decodeSPVPong(buffer[:n])
|
||||
|
||||
if pong == nil {
|
||||
return "", errors.Base("Pong decoding failed")
|
||||
}
|
||||
|
||||
myAddr := pong.DecodeAddress()
|
||||
|
||||
return myAddr, nil
|
||||
}
|
||||
|
||||
// UDPServer is a goroutine that starts an udp server that implements the hubs
|
||||
// Ping/Pong protocol to find out about each other without making full TCP
|
||||
// connections.
|
||||
func UDPServer(args *Args) error {
|
||||
address := ":" + args.UDPPort
|
||||
tip := make([]byte, 32)
|
||||
addr, err := net.ResolveUDPAddr("udp", address)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
conn, err := net.ListenUDP("udp", addr)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
defer conn.Close()
|
||||
|
||||
buffer := make([]byte, maxBufferSize)
|
||||
for {
|
||||
//TODO verify ping
|
||||
_, addr, err := conn.ReadFromUDP(buffer)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
sAddr := addr.IP.String()
|
||||
pong := makeSPVPong(0,0, tip, sAddr, args.Country)
|
||||
data := pong.Encode()
|
||||
|
||||
_, err = conn.WriteToUDP(data, addr)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue