diff --git a/db/db.go b/db/db.go index 1639de6..6d484b0 100644 --- a/db/db.go +++ b/db/db.go @@ -10,8 +10,8 @@ import ( "github.com/lbryio/hub/db/db_stack" "github.com/lbryio/hub/db/prefixes" + "github.com/lbryio/hub/internal" "github.com/lbryio/hub/internal/metrics" - "github.com/lbryio/lbry.go/v2/extras/util" "github.com/linxGnu/grocksdb" log "github.com/sirupsen/logrus" @@ -248,7 +248,7 @@ type PathSegment struct { } func (ps *PathSegment) Normalized() string { - return util.NormalizeName(ps.name) + return internal.NormalizeName(ps.name) } func (ps *PathSegment) IsShortId() bool { diff --git a/db/db_resolve.go b/db/db_resolve.go index 8d93f5a..ebae14d 100644 --- a/db/db_resolve.go +++ b/db/db_resolve.go @@ -9,8 +9,8 @@ import ( "strings" "github.com/lbryio/hub/db/prefixes" + "github.com/lbryio/hub/internal" pb "github.com/lbryio/hub/protobuf/go" - "github.com/lbryio/lbry.go/v2/extras/util" lbryurl "github.com/lbryio/lbry.go/v3/url" log "github.com/sirupsen/logrus" ) @@ -27,7 +27,7 @@ func PrepareResolveResult( activationHeight uint32, signatureValid bool) (*ResolveResult, error) { - normalizedName := util.NormalizeName(name) + normalizedName := internal.NormalizeName(name) controllingClaim, err := GetControllingClaim(db, normalizedName) if err != nil { return nil, err @@ -165,7 +165,7 @@ func PrepareResolveResult( } func ResolveParsedUrl(db *ReadOnlyDBColumnFamily, parsed *PathSegment) (*ResolveResult, error) { - normalizedName := util.NormalizeName(parsed.name) + normalizedName := internal.NormalizeName(parsed.name) if (parsed.amountOrder == -1 && parsed.claimId == "") || parsed.amountOrder == 1 { log.Warn("Resolving claim by name") ch := ControllingClaimIter(db) diff --git a/db/db_test.go b/db/db_test.go index ecb2d7d..0e004fd 100644 --- a/db/db_test.go +++ b/db/db_test.go @@ -11,7 +11,7 @@ import ( dbpkg "github.com/lbryio/hub/db" "github.com/lbryio/hub/db/prefixes" - "github.com/lbryio/lbry.go/v2/extras/util" + "github.com/lbryio/hub/internal" "github.com/linxGnu/grocksdb" ) @@ -429,7 +429,7 @@ func TestPrintClaimShortId(t *testing.T) { // TestGetShortClaimIdUrl tests resolving a claim to a short url. func TestGetShortClaimIdUrl(t *testing.T) { name := "@Styxhexenhammer666" - normalName := util.NormalizeName(name) + normalName := internal.NormalizeName(name) claimHash, _ := hex.DecodeString("2556ed1cab9d17f2a9392030a9ad7f5d138f11bd") // claimHash := []byte{} var rootTxNum uint32 = 0x61ec7c @@ -685,7 +685,7 @@ func TestPrintClaimTakeover(t *testing.T) { // TestGetControlingClaim Tests getting a controlling claim value from the db // based on a name. func TestGetControllingClaim(t *testing.T) { - claimName := util.NormalizeName("@Styxhexenhammer666") + claimName := internal.NormalizeName("@Styxhexenhammer666") claimHash := "2556ed1cab9d17f2a9392030a9ad7f5d138f11bd" filePath := "../testdata/P_resolve.csv" db, _, toDefer, err := OpenAndFillTmpDBColumnFamlies(filePath) diff --git a/db/prefixes/prefixes.go b/db/prefixes/prefixes.go index 5a4827b..c7933ff 100644 --- a/db/prefixes/prefixes.go +++ b/db/prefixes/prefixes.go @@ -10,8 +10,7 @@ import ( "sort" "strings" - "github.com/lbryio/lbry.go/v2/extras/errors" - "github.com/lbryio/lbry.go/v2/extras/util" + "github.com/lbryio/hub/internal" ) const ( @@ -1367,7 +1366,7 @@ func NewClaimToTXOKey(claimHash []byte) *ClaimToTXOKey { func (v *ClaimToTXOValue) NormalizedName() string { //TODO implement? Might not need to do anything. - return util.NormalizeName(v.Name) + return internal.NormalizeName(v.Name) } func (k *ClaimToTXOKey) PackKey() []byte { @@ -4084,29 +4083,29 @@ func generic(voidstar interface{}, firstByte byte, function byte, functionName s return BlockTxsKeyPackPartialKey(voidstar.(*BlockTxsKey)), nil } - return nil, errors.Base("%s function for %v not implemented", functionName, firstByte) + return nil, fmt.Errorf("%s function for %v not implemented", functionName, firstByte) } func UnpackGenericKey(key []byte) (interface{}, error) { if len(key) == 0 { - return nil, errors.Base("key length zero") + return nil, fmt.Errorf("key length zero") } return generic(key, key[0], 0, "unpack key") } func UnpackGenericValue(key, value []byte) (interface{}, error) { if len(key) == 0 { - return nil, errors.Base("key length zero") + return nil, fmt.Errorf("key length zero") } if len(value) == 0 { - return nil, errors.Base("value length zero") + return nil, fmt.Errorf("value length zero") } return generic(value, key[0], 1, "unpack value") } func PackPartialGenericKey(prefix byte, key interface{}, nFields int) ([]byte, error) { if key == nil { - return nil, errors.Base("key length zero") + return nil, fmt.Errorf("key length zero") } genericRes, err := generic(key, prefix, 4, "pack partial key") res := genericRes.(func(int) []byte)(nFields) @@ -4115,7 +4114,7 @@ func PackPartialGenericKey(prefix byte, key interface{}, nFields int) ([]byte, e func PackGenericKey(prefix byte, key interface{}) ([]byte, error) { if key == nil { - return nil, errors.Base("key length zero") + return nil, fmt.Errorf("key length zero") } genericRes, err := generic(key, prefix, 2, "pack key") return genericRes.([]byte), err @@ -4123,7 +4122,7 @@ func PackGenericKey(prefix byte, key interface{}) ([]byte, error) { func PackGenericValue(prefix byte, value interface{}) ([]byte, error) { if value == nil { - return nil, errors.Base("value length zero") + return nil, fmt.Errorf("value length zero") } genericRes, err := generic(value, prefix, 3, "pack value") return genericRes.([]byte), err diff --git a/internal/strings.go b/internal/strings.go new file mode 100644 index 0000000..7562b44 --- /dev/null +++ b/internal/strings.go @@ -0,0 +1,54 @@ +package internal + +import ( + "encoding/hex" + "strings" + + "golang.org/x/text/cases" + "golang.org/x/text/unicode/norm" +) + +func StringSplitArg(stringToSplit, separator string) []interface{} { + split := strings.Split(stringToSplit, separator) + splitInterface := make([]interface{}, len(split)) + for i, s := range split { + splitInterface[i] = s + } + return splitInterface +} + +// NormalizeName Normalize names to remove weird characters and account to capitalization +func NormalizeName(s string) string { + c := cases.Fold() + return c.String(norm.NFD.String(s)) +} + +// ReverseBytesInPlace reverse the bytes. thanks, Satoshi 😒 +func ReverseBytesInPlace(s []byte) { + for i, j := 0, len(s)-1; i < j; i, j = i+1, j-1 { + s[i], s[j] = s[j], s[i] + } +} + +// TxIdToTxHash convert the txid to a hash for returning from the hub +func TxIdToTxHash(txid string) []byte { + t, err := hex.DecodeString(txid) + if err != nil { + return nil + } + + ReverseBytesInPlace(t) + + return t +} + +// TxHashToTxId convert the txHash from the response format back to an id +func TxHashToTxId(txHash []byte) string { + t := make([]byte, len(txHash)) + copy(t, txHash) + + ReverseBytesInPlace(t) + + return hex.EncodeToString(t) + +} diff --git a/protobuf/definitions/hub.proto b/protobuf/definitions/hub.proto index a2dc484..4a71b14 100644 --- a/protobuf/definitions/hub.proto +++ b/protobuf/definitions/hub.proto @@ -14,6 +14,7 @@ service Hub { rpc Version(EmptyMessage) returns (StringValue) {} rpc Features(EmptyMessage) returns (StringValue) {} rpc Broadcast(EmptyMessage) returns (UInt32Value) {} + rpc Height(EmptyMessage) returns (UInt32Value) {} rpc Resolve(StringArray) returns (Outputs) {} } diff --git a/protobuf/go/hub.pb.go b/protobuf/go/hub.pb.go index 33c47a8..1cd10a9 100644 --- a/protobuf/go/hub.pb.go +++ b/protobuf/go/hub.pb.go @@ -1175,7 +1175,7 @@ var file_hub_proto_rawDesc = []byte{ 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, 0xb3, 0x03, 0x0a, 0x03, + 0x08, 0x52, 0x08, 0x6e, 0x6f, 0x54, 0x6f, 0x74, 0x61, 0x6c, 0x73, 0x32, 0xe2, 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, @@ -1200,13 +1200,15 @@ var file_hub_proto_rawDesc = []byte{ 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, 0x12, 0x29, 0x0a, 0x07, 0x52, 0x65, 0x73, 0x6f, 0x6c, 0x76, - 0x65, 0x12, 0x0f, 0x2e, 0x70, 0x62, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x41, 0x72, 0x72, - 0x61, 0x79, 0x1a, 0x0b, 0x2e, 0x70, 0x62, 0x2e, 0x4f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x73, 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, + 0x61, 0x6c, 0x75, 0x65, 0x22, 0x00, 0x12, 0x2d, 0x0a, 0x06, 0x48, 0x65, 0x69, 0x67, 0x68, 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, 0x12, 0x29, 0x0a, 0x07, 0x52, 0x65, 0x73, 0x6f, 0x6c, 0x76, 0x65, + 0x12, 0x0f, 0x2e, 0x70, 0x62, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x41, 0x72, 0x72, 0x61, + 0x79, 0x1a, 0x0b, 0x2e, 0x70, 0x62, 0x2e, 0x4f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x73, 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 ( @@ -1269,18 +1271,20 @@ var file_hub_proto_depIdxs = []int32{ 1, // 28: pb.Hub.Version:input_type -> pb.EmptyMessage 1, // 29: pb.Hub.Features:input_type -> pb.EmptyMessage 1, // 30: pb.Hub.Broadcast:input_type -> pb.EmptyMessage - 6, // 31: pb.Hub.Resolve:input_type -> pb.StringArray - 11, // 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 - 8, // 39: pb.Hub.Broadcast:output_type -> pb.UInt32Value - 11, // 40: pb.Hub.Resolve:output_type -> pb.Outputs - 32, // [32:41] is the sub-list for method output_type - 23, // [23:32] is the sub-list for method input_type + 1, // 31: pb.Hub.Height:input_type -> pb.EmptyMessage + 6, // 32: pb.Hub.Resolve:input_type -> pb.StringArray + 11, // 33: pb.Hub.Search:output_type -> pb.Outputs + 5, // 34: pb.Hub.Ping:output_type -> pb.StringValue + 3, // 35: pb.Hub.Hello:output_type -> pb.HelloMessage + 5, // 36: pb.Hub.AddPeer:output_type -> pb.StringValue + 5, // 37: pb.Hub.PeerSubscribe:output_type -> pb.StringValue + 5, // 38: pb.Hub.Version:output_type -> pb.StringValue + 5, // 39: pb.Hub.Features:output_type -> pb.StringValue + 8, // 40: pb.Hub.Broadcast:output_type -> pb.UInt32Value + 8, // 41: pb.Hub.Height:output_type -> pb.UInt32Value + 11, // 42: pb.Hub.Resolve:output_type -> pb.Outputs + 33, // [33:43] is the sub-list for method output_type + 23, // [23:33] 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 diff --git a/protobuf/go/hub_grpc.pb.go b/protobuf/go/hub_grpc.pb.go index feec0b6..b19176a 100644 --- a/protobuf/go/hub_grpc.pb.go +++ b/protobuf/go/hub_grpc.pb.go @@ -26,6 +26,7 @@ type HubClient interface { 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) + Height(ctx context.Context, in *EmptyMessage, opts ...grpc.CallOption) (*UInt32Value, error) Resolve(ctx context.Context, in *StringArray, opts ...grpc.CallOption) (*Outputs, error) } @@ -109,6 +110,15 @@ func (c *hubClient) Broadcast(ctx context.Context, in *EmptyMessage, opts ...grp return out, nil } +func (c *hubClient) Height(ctx context.Context, in *EmptyMessage, opts ...grpc.CallOption) (*UInt32Value, error) { + out := new(UInt32Value) + err := c.cc.Invoke(ctx, "/pb.Hub/Height", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + func (c *hubClient) Resolve(ctx context.Context, in *StringArray, opts ...grpc.CallOption) (*Outputs, error) { out := new(Outputs) err := c.cc.Invoke(ctx, "/pb.Hub/Resolve", in, out, opts...) @@ -130,6 +140,7 @@ type HubServer interface { Version(context.Context, *EmptyMessage) (*StringValue, error) Features(context.Context, *EmptyMessage) (*StringValue, error) Broadcast(context.Context, *EmptyMessage) (*UInt32Value, error) + Height(context.Context, *EmptyMessage) (*UInt32Value, error) Resolve(context.Context, *StringArray) (*Outputs, error) mustEmbedUnimplementedHubServer() } @@ -162,6 +173,9 @@ func (UnimplementedHubServer) Features(context.Context, *EmptyMessage) (*StringV func (UnimplementedHubServer) Broadcast(context.Context, *EmptyMessage) (*UInt32Value, error) { return nil, status.Errorf(codes.Unimplemented, "method Broadcast not implemented") } +func (UnimplementedHubServer) Height(context.Context, *EmptyMessage) (*UInt32Value, error) { + return nil, status.Errorf(codes.Unimplemented, "method Height not implemented") +} func (UnimplementedHubServer) Resolve(context.Context, *StringArray) (*Outputs, error) { return nil, status.Errorf(codes.Unimplemented, "method Resolve not implemented") } @@ -322,6 +336,24 @@ func _Hub_Broadcast_Handler(srv interface{}, ctx context.Context, dec func(inter return interceptor(ctx, in, info, handler) } +func _Hub_Height_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(EmptyMessage) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(HubServer).Height(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/pb.Hub/Height", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(HubServer).Height(ctx, req.(*EmptyMessage)) + } + return interceptor(ctx, in, info, handler) +} + func _Hub_Resolve_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(StringArray) if err := dec(in); err != nil { @@ -379,6 +411,10 @@ var Hub_ServiceDesc = grpc.ServiceDesc{ MethodName: "Broadcast", Handler: _Hub_Broadcast_Handler, }, + { + MethodName: "Height", + Handler: _Hub_Height_Handler, + }, { MethodName: "Resolve", Handler: _Hub_Resolve_Handler, diff --git a/protobuf/python/hub_pb2.py b/protobuf/python/hub_pb2.py index 4065c06..b0d3617 100644 --- a/protobuf/python/hub_pb2.py +++ b/protobuf/python/hub_pb2.py @@ -20,7 +20,7 @@ DESCRIPTOR = _descriptor.FileDescriptor( syntax='proto3', serialized_options=b'Z$github.com/lbryio/hub/protobuf/go/pb', create_key=_descriptor._internal_create_key, - serialized_pb=b'\n\thub.proto\x12\x02pb\x1a\x0cresult.proto\"\x0e\n\x0c\x45mptyMessage\".\n\rServerMessage\x12\x0f\n\x07\x61\x64\x64ress\x18\x01 \x01(\t\x12\x0c\n\x04port\x18\x02 \x01(\t\"N\n\x0cHelloMessage\x12\x0c\n\x04port\x18\x01 \x01(\t\x12\x0c\n\x04host\x18\x02 \x01(\t\x12\"\n\x07servers\x18\x03 \x03(\x0b\x32\x11.pb.ServerMessage\"0\n\x0fInvertibleField\x12\x0e\n\x06invert\x18\x01 \x01(\x08\x12\r\n\x05value\x18\x02 \x03(\t\"\x1c\n\x0bStringValue\x12\r\n\x05value\x18\x01 \x01(\t\"\x1c\n\x0bStringArray\x12\r\n\x05value\x18\x01 \x03(\t\"\x1a\n\tBoolValue\x12\r\n\x05value\x18\x01 \x01(\x08\"\x1c\n\x0bUInt32Value\x12\r\n\x05value\x18\x01 \x01(\r\"j\n\nRangeField\x12\x1d\n\x02op\x18\x01 \x01(\x0e\x32\x11.pb.RangeField.Op\x12\r\n\x05value\x18\x02 \x03(\x05\".\n\x02Op\x12\x06\n\x02\x45Q\x10\x00\x12\x07\n\x03LTE\x10\x01\x12\x07\n\x03GTE\x10\x02\x12\x06\n\x02LT\x10\x03\x12\x06\n\x02GT\x10\x04\"\xfd\x0b\n\rSearchRequest\x12%\n\x08\x63laim_id\x18\x01 \x01(\x0b\x32\x13.pb.InvertibleField\x12\'\n\nchannel_id\x18\x02 \x01(\x0b\x32\x13.pb.InvertibleField\x12\x0c\n\x04text\x18\x03 \x01(\t\x12\r\n\x05limit\x18\x04 \x01(\x05\x12\x10\n\x08order_by\x18\x05 \x03(\t\x12\x0e\n\x06offset\x18\x06 \x01(\r\x12\x16\n\x0eis_controlling\x18\x07 \x01(\x08\x12\x1d\n\x15last_take_over_height\x18\x08 \x01(\t\x12\x12\n\nclaim_name\x18\t \x01(\t\x12\x17\n\x0fnormalized_name\x18\n \x01(\t\x12#\n\x0btx_position\x18\x0b \x03(\x0b\x32\x0e.pb.RangeField\x12\x1e\n\x06\x61mount\x18\x0c \x03(\x0b\x32\x0e.pb.RangeField\x12!\n\ttimestamp\x18\r \x03(\x0b\x32\x0e.pb.RangeField\x12*\n\x12\x63reation_timestamp\x18\x0e \x03(\x0b\x32\x0e.pb.RangeField\x12\x1e\n\x06height\x18\x0f \x03(\x0b\x32\x0e.pb.RangeField\x12\'\n\x0f\x63reation_height\x18\x10 \x03(\x0b\x32\x0e.pb.RangeField\x12)\n\x11\x61\x63tivation_height\x18\x11 \x03(\x0b\x32\x0e.pb.RangeField\x12)\n\x11\x65xpiration_height\x18\x12 \x03(\x0b\x32\x0e.pb.RangeField\x12$\n\x0crelease_time\x18\x13 \x03(\x0b\x32\x0e.pb.RangeField\x12\x11\n\tshort_url\x18\x14 \x01(\t\x12\x15\n\rcanonical_url\x18\x15 \x01(\t\x12\r\n\x05title\x18\x16 \x01(\t\x12\x0e\n\x06\x61uthor\x18\x17 \x01(\t\x12\x13\n\x0b\x64\x65scription\x18\x18 \x01(\t\x12\x12\n\nclaim_type\x18\x19 \x03(\t\x12$\n\x0crepost_count\x18\x1a \x03(\x0b\x32\x0e.pb.RangeField\x12\x13\n\x0bstream_type\x18\x1b \x03(\t\x12\x12\n\nmedia_type\x18\x1c \x03(\t\x12\"\n\nfee_amount\x18\x1d \x03(\x0b\x32\x0e.pb.RangeField\x12\x14\n\x0c\x66\x65\x65_currency\x18\x1e \x01(\t\x12 \n\x08\x64uration\x18\x1f \x03(\x0b\x32\x0e.pb.RangeField\x12\x19\n\x11reposted_claim_id\x18 \x01(\t\x12#\n\x0b\x63\x65nsor_type\x18! \x03(\x0b\x32\x0e.pb.RangeField\x12\x19\n\x11\x63laims_in_channel\x18\" \x01(\t\x12)\n\x12is_signature_valid\x18$ \x01(\x0b\x32\r.pb.BoolValue\x12(\n\x10\x65\x66\x66\x65\x63tive_amount\x18% \x03(\x0b\x32\x0e.pb.RangeField\x12&\n\x0esupport_amount\x18& \x03(\x0b\x32\x0e.pb.RangeField\x12&\n\x0etrending_score\x18\' \x03(\x0b\x32\x0e.pb.RangeField\x12\r\n\x05tx_id\x18+ \x01(\t\x12 \n\x07tx_nout\x18, \x01(\x0b\x32\x0f.pb.UInt32Value\x12\x11\n\tsignature\x18- \x01(\t\x12\x18\n\x10signature_digest\x18. \x01(\t\x12\x18\n\x10public_key_bytes\x18/ \x01(\t\x12\x15\n\rpublic_key_id\x18\x30 \x01(\t\x12\x10\n\x08\x61ny_tags\x18\x31 \x03(\t\x12\x10\n\x08\x61ll_tags\x18\x32 \x03(\t\x12\x10\n\x08not_tags\x18\x33 \x03(\t\x12\x1d\n\x15has_channel_signature\x18\x34 \x01(\x08\x12!\n\nhas_source\x18\x35 \x01(\x0b\x32\r.pb.BoolValue\x12 \n\x18limit_claims_per_channel\x18\x36 \x01(\x05\x12\x15\n\rany_languages\x18\x37 \x03(\t\x12\x15\n\rall_languages\x18\x38 \x03(\t\x12\x19\n\x11remove_duplicates\x18\x39 \x01(\x08\x12\x11\n\tno_totals\x18: \x01(\x08\x32\xb3\x03\n\x03Hub\x12*\n\x06Search\x12\x11.pb.SearchRequest\x1a\x0b.pb.Outputs\"\x00\x12+\n\x04Ping\x12\x10.pb.EmptyMessage\x1a\x0f.pb.StringValue\"\x00\x12-\n\x05Hello\x12\x10.pb.HelloMessage\x1a\x10.pb.HelloMessage\"\x00\x12/\n\x07\x41\x64\x64Peer\x12\x11.pb.ServerMessage\x1a\x0f.pb.StringValue\"\x00\x12\x35\n\rPeerSubscribe\x12\x11.pb.ServerMessage\x1a\x0f.pb.StringValue\"\x00\x12.\n\x07Version\x12\x10.pb.EmptyMessage\x1a\x0f.pb.StringValue\"\x00\x12/\n\x08\x46\x65\x61tures\x12\x10.pb.EmptyMessage\x1a\x0f.pb.StringValue\"\x00\x12\x30\n\tBroadcast\x12\x10.pb.EmptyMessage\x1a\x0f.pb.UInt32Value\"\x00\x12)\n\x07Resolve\x12\x0f.pb.StringArray\x1a\x0b.pb.Outputs\"\x00\x42&Z$github.com/lbryio/hub/protobuf/go/pbb\x06proto3' + serialized_pb=b'\n\thub.proto\x12\x02pb\x1a\x0cresult.proto\"\x0e\n\x0c\x45mptyMessage\".\n\rServerMessage\x12\x0f\n\x07\x61\x64\x64ress\x18\x01 \x01(\t\x12\x0c\n\x04port\x18\x02 \x01(\t\"N\n\x0cHelloMessage\x12\x0c\n\x04port\x18\x01 \x01(\t\x12\x0c\n\x04host\x18\x02 \x01(\t\x12\"\n\x07servers\x18\x03 \x03(\x0b\x32\x11.pb.ServerMessage\"0\n\x0fInvertibleField\x12\x0e\n\x06invert\x18\x01 \x01(\x08\x12\r\n\x05value\x18\x02 \x03(\t\"\x1c\n\x0bStringValue\x12\r\n\x05value\x18\x01 \x01(\t\"\x1c\n\x0bStringArray\x12\r\n\x05value\x18\x01 \x03(\t\"\x1a\n\tBoolValue\x12\r\n\x05value\x18\x01 \x01(\x08\"\x1c\n\x0bUInt32Value\x12\r\n\x05value\x18\x01 \x01(\r\"j\n\nRangeField\x12\x1d\n\x02op\x18\x01 \x01(\x0e\x32\x11.pb.RangeField.Op\x12\r\n\x05value\x18\x02 \x03(\x05\".\n\x02Op\x12\x06\n\x02\x45Q\x10\x00\x12\x07\n\x03LTE\x10\x01\x12\x07\n\x03GTE\x10\x02\x12\x06\n\x02LT\x10\x03\x12\x06\n\x02GT\x10\x04\"\xfd\x0b\n\rSearchRequest\x12%\n\x08\x63laim_id\x18\x01 \x01(\x0b\x32\x13.pb.InvertibleField\x12\'\n\nchannel_id\x18\x02 \x01(\x0b\x32\x13.pb.InvertibleField\x12\x0c\n\x04text\x18\x03 \x01(\t\x12\r\n\x05limit\x18\x04 \x01(\x05\x12\x10\n\x08order_by\x18\x05 \x03(\t\x12\x0e\n\x06offset\x18\x06 \x01(\r\x12\x16\n\x0eis_controlling\x18\x07 \x01(\x08\x12\x1d\n\x15last_take_over_height\x18\x08 \x01(\t\x12\x12\n\nclaim_name\x18\t \x01(\t\x12\x17\n\x0fnormalized_name\x18\n \x01(\t\x12#\n\x0btx_position\x18\x0b \x03(\x0b\x32\x0e.pb.RangeField\x12\x1e\n\x06\x61mount\x18\x0c \x03(\x0b\x32\x0e.pb.RangeField\x12!\n\ttimestamp\x18\r \x03(\x0b\x32\x0e.pb.RangeField\x12*\n\x12\x63reation_timestamp\x18\x0e \x03(\x0b\x32\x0e.pb.RangeField\x12\x1e\n\x06height\x18\x0f \x03(\x0b\x32\x0e.pb.RangeField\x12\'\n\x0f\x63reation_height\x18\x10 \x03(\x0b\x32\x0e.pb.RangeField\x12)\n\x11\x61\x63tivation_height\x18\x11 \x03(\x0b\x32\x0e.pb.RangeField\x12)\n\x11\x65xpiration_height\x18\x12 \x03(\x0b\x32\x0e.pb.RangeField\x12$\n\x0crelease_time\x18\x13 \x03(\x0b\x32\x0e.pb.RangeField\x12\x11\n\tshort_url\x18\x14 \x01(\t\x12\x15\n\rcanonical_url\x18\x15 \x01(\t\x12\r\n\x05title\x18\x16 \x01(\t\x12\x0e\n\x06\x61uthor\x18\x17 \x01(\t\x12\x13\n\x0b\x64\x65scription\x18\x18 \x01(\t\x12\x12\n\nclaim_type\x18\x19 \x03(\t\x12$\n\x0crepost_count\x18\x1a \x03(\x0b\x32\x0e.pb.RangeField\x12\x13\n\x0bstream_type\x18\x1b \x03(\t\x12\x12\n\nmedia_type\x18\x1c \x03(\t\x12\"\n\nfee_amount\x18\x1d \x03(\x0b\x32\x0e.pb.RangeField\x12\x14\n\x0c\x66\x65\x65_currency\x18\x1e \x01(\t\x12 \n\x08\x64uration\x18\x1f \x03(\x0b\x32\x0e.pb.RangeField\x12\x19\n\x11reposted_claim_id\x18 \x01(\t\x12#\n\x0b\x63\x65nsor_type\x18! \x03(\x0b\x32\x0e.pb.RangeField\x12\x19\n\x11\x63laims_in_channel\x18\" \x01(\t\x12)\n\x12is_signature_valid\x18$ \x01(\x0b\x32\r.pb.BoolValue\x12(\n\x10\x65\x66\x66\x65\x63tive_amount\x18% \x03(\x0b\x32\x0e.pb.RangeField\x12&\n\x0esupport_amount\x18& \x03(\x0b\x32\x0e.pb.RangeField\x12&\n\x0etrending_score\x18\' \x03(\x0b\x32\x0e.pb.RangeField\x12\r\n\x05tx_id\x18+ \x01(\t\x12 \n\x07tx_nout\x18, \x01(\x0b\x32\x0f.pb.UInt32Value\x12\x11\n\tsignature\x18- \x01(\t\x12\x18\n\x10signature_digest\x18. \x01(\t\x12\x18\n\x10public_key_bytes\x18/ \x01(\t\x12\x15\n\rpublic_key_id\x18\x30 \x01(\t\x12\x10\n\x08\x61ny_tags\x18\x31 \x03(\t\x12\x10\n\x08\x61ll_tags\x18\x32 \x03(\t\x12\x10\n\x08not_tags\x18\x33 \x03(\t\x12\x1d\n\x15has_channel_signature\x18\x34 \x01(\x08\x12!\n\nhas_source\x18\x35 \x01(\x0b\x32\r.pb.BoolValue\x12 \n\x18limit_claims_per_channel\x18\x36 \x01(\x05\x12\x15\n\rany_languages\x18\x37 \x03(\t\x12\x15\n\rall_languages\x18\x38 \x03(\t\x12\x19\n\x11remove_duplicates\x18\x39 \x01(\x08\x12\x11\n\tno_totals\x18: \x01(\x08\x32\xe2\x03\n\x03Hub\x12*\n\x06Search\x12\x11.pb.SearchRequest\x1a\x0b.pb.Outputs\"\x00\x12+\n\x04Ping\x12\x10.pb.EmptyMessage\x1a\x0f.pb.StringValue\"\x00\x12-\n\x05Hello\x12\x10.pb.HelloMessage\x1a\x10.pb.HelloMessage\"\x00\x12/\n\x07\x41\x64\x64Peer\x12\x11.pb.ServerMessage\x1a\x0f.pb.StringValue\"\x00\x12\x35\n\rPeerSubscribe\x12\x11.pb.ServerMessage\x1a\x0f.pb.StringValue\"\x00\x12.\n\x07Version\x12\x10.pb.EmptyMessage\x1a\x0f.pb.StringValue\"\x00\x12/\n\x08\x46\x65\x61tures\x12\x10.pb.EmptyMessage\x1a\x0f.pb.StringValue\"\x00\x12\x30\n\tBroadcast\x12\x10.pb.EmptyMessage\x1a\x0f.pb.UInt32Value\"\x00\x12-\n\x06Height\x12\x10.pb.EmptyMessage\x1a\x0f.pb.UInt32Value\"\x00\x12)\n\x07Resolve\x12\x0f.pb.StringArray\x1a\x0b.pb.Outputs\"\x00\x42&Z$github.com/lbryio/hub/protobuf/go/pbb\x06proto3' , dependencies=[result__pb2.DESCRIPTOR,]) @@ -903,7 +903,7 @@ _HUB = _descriptor.ServiceDescriptor( serialized_options=None, create_key=_descriptor._internal_create_key, serialized_start=1988, - serialized_end=2423, + serialized_end=2470, methods=[ _descriptor.MethodDescriptor( name='Search', @@ -985,10 +985,20 @@ _HUB = _descriptor.ServiceDescriptor( serialized_options=None, create_key=_descriptor._internal_create_key, ), + _descriptor.MethodDescriptor( + name='Height', + full_name='pb.Hub.Height', + index=8, + containing_service=None, + input_type=_EMPTYMESSAGE, + output_type=_UINT32VALUE, + serialized_options=None, + create_key=_descriptor._internal_create_key, + ), _descriptor.MethodDescriptor( name='Resolve', full_name='pb.Hub.Resolve', - index=8, + index=9, containing_service=None, input_type=_STRINGARRAY, output_type=result__pb2._OUTPUTS, diff --git a/protobuf/python/hub_pb2_grpc.py b/protobuf/python/hub_pb2_grpc.py index e35227c..e00c385 100644 --- a/protobuf/python/hub_pb2_grpc.py +++ b/protobuf/python/hub_pb2_grpc.py @@ -55,6 +55,11 @@ class HubStub(object): request_serializer=hub__pb2.EmptyMessage.SerializeToString, response_deserializer=hub__pb2.UInt32Value.FromString, ) + self.Height = channel.unary_unary( + '/pb.Hub/Height', + request_serializer=hub__pb2.EmptyMessage.SerializeToString, + response_deserializer=hub__pb2.UInt32Value.FromString, + ) self.Resolve = channel.unary_unary( '/pb.Hub/Resolve', request_serializer=hub__pb2.StringArray.SerializeToString, @@ -113,6 +118,12 @@ class HubServicer(object): context.set_details('Method not implemented!') raise NotImplementedError('Method not implemented!') + def Height(self, request, context): + """Missing associated documentation comment in .proto file.""" + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + def Resolve(self, request, context): """Missing associated documentation comment in .proto file.""" context.set_code(grpc.StatusCode.UNIMPLEMENTED) @@ -162,6 +173,11 @@ def add_HubServicer_to_server(servicer, server): request_deserializer=hub__pb2.EmptyMessage.FromString, response_serializer=hub__pb2.UInt32Value.SerializeToString, ), + 'Height': grpc.unary_unary_rpc_method_handler( + servicer.Height, + request_deserializer=hub__pb2.EmptyMessage.FromString, + response_serializer=hub__pb2.UInt32Value.SerializeToString, + ), 'Resolve': grpc.unary_unary_rpc_method_handler( servicer.Resolve, request_deserializer=hub__pb2.StringArray.FromString, @@ -313,6 +329,23 @@ class Hub(object): options, channel_credentials, insecure, call_credentials, compression, wait_for_ready, timeout, metadata) + @staticmethod + def Height(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary(request, target, '/pb.Hub/Height', + hub__pb2.EmptyMessage.SerializeToString, + hub__pb2.UInt32Value.FromString, + options, channel_credentials, + insecure, call_credentials, compression, wait_for_ready, timeout, metadata) + @staticmethod def Resolve(request, target, diff --git a/server/search.go b/server/search.go index f357f92..a6b4911 100644 --- a/server/search.go +++ b/server/search.go @@ -10,9 +10,9 @@ import ( "strings" "time" + "github.com/lbryio/hub/internal" "github.com/lbryio/hub/internal/metrics" pb "github.com/lbryio/hub/protobuf/go" - "github.com/lbryio/lbry.go/v2/extras/util" "github.com/olivere/elastic/v7" "github.com/prometheus/client_golang/prometheus" "golang.org/x/text/cases" @@ -475,7 +475,7 @@ func (s *Server) checkQuery(in *pb.SearchRequest) error { } for name, failed := range checks { if failed { - time.Sleep(2) // throttle + time.Sleep(time.Second * 2) // throttle return fmt.Errorf("%s cant have more than %d items.", name, limit) } } @@ -555,7 +555,7 @@ func (s *Server) setupEsQuery( } if len(in.ClaimName) > 0 { - in.NormalizedName = util.NormalizeName(in.ClaimName) + in.NormalizedName = internal.NormalizeName(in.ClaimName) } if len(in.OrderBy) > 0 { @@ -872,7 +872,7 @@ func searchAhead(searchHits []*record, pageSize int, perChannelPerPage int) []*r // struct. func (r *record) recordToOutput() *pb.Output { return &pb.Output{ - TxHash: util.TxIdToTxHash(r.Txid), + TxHash: internal.TxIdToTxHash(r.Txid), Nout: r.Nout, Height: r.Height, Meta: &pb.Output_Claim{ diff --git a/server/server.go b/server/server.go index ab8ad3f..d482329 100644 --- a/server/server.go +++ b/server/server.go @@ -363,60 +363,14 @@ func (s *Server) Version(ctx context.Context, args *pb.EmptyMessage) (*pb.String return &pb.StringValue{Value: getVersion()}, nil } -/* - async def claimtrie_resolve(self, *urls) -> str: - sorted_urls = tuple(sorted(urls)) - self.session_manager.urls_to_resolve_count_metric.inc(len(sorted_urls)) - try: - if sorted_urls in self.session_manager.resolve_outputs_cache: - return self.session_manager.resolve_outputs_cache[sorted_urls] - rows, extra = [], [] - for url in urls: - if url not in self.session_manager.resolve_cache: - self.session_manager.resolve_cache[url] = await self._cached_resolve_url(url) - stream, channel, repost, reposted_channel = self.session_manager.resolve_cache[url] - if isinstance(channel, ResolveCensoredError): - rows.append(channel) - extra.append(channel.censor_row) - elif isinstance(stream, ResolveCensoredError): - rows.append(stream) - extra.append(stream.censor_row) - elif channel and not stream: - rows.append(channel) - # print("resolved channel", channel.name.decode()) - if repost: - extra.append(repost) - if reposted_channel: - extra.append(reposted_channel) - elif stream: - # print("resolved stream", stream.name.decode()) - rows.append(stream) - if channel: - # print("and channel", channel.name.decode()) - extra.append(channel) - if repost: - extra.append(repost) - if reposted_channel: - extra.append(reposted_channel) - await asyncio.sleep(0) - self.session_manager.resolve_outputs_cache[sorted_urls] = result = await self.loop.run_in_executor( - None, Outputs.to_base64, rows, extra, 0, None, None - ) - return result - finally: - self.session_manager.resolved_url_count_metric.inc(len(sorted_urls)) -*/ - -// type OutputWType struct { -// Output *pb.Output -// OutputType byte -// } - -// const ( -// OutputChannelType = iota -// OutputRepostType = iota -// OutputErrorType = iota -// ) +func (s *Server) Height(ctx context.Context, args *pb.EmptyMessage) (*pb.UInt32Value, error) { + metrics.RequestsCount.With(prometheus.Labels{"method": "height"}).Inc() + if s.DB != nil { + return &pb.UInt32Value{Value: s.DB.LastState.Height}, nil + } else { + return &pb.UInt32Value{Value: 0}, nil + } +} func ResolveResultToOutput(res *db.ResolveResult) *pb.Output { // func ResolveResultToOutput(res *db.ResolveResult, outputType byte) *OutputWType { diff --git a/server/udp.go b/server/udp.go index eef6552..1ef171c 100644 --- a/server/udp.go +++ b/server/udp.go @@ -2,13 +2,13 @@ package server import ( "encoding/binary" + "fmt" "net" "strconv" "strings" "time" pb "github.com/lbryio/hub/protobuf/go" - "github.com/lbryio/lbry.go/v2/extras/errors" ) const maxBufferSize = 1024 @@ -210,7 +210,7 @@ func UDPPing(ip, port string) (*SPVPong, error) { pong := decodeSPVPong(buffer[:n]) if pong == nil { - return nil, errors.Base("Pong decoding failed") + return nil, fmt.Errorf("Pong decoding failed") } return pong, nil