From 74023fe23046240022a57e6149470ca614758616 Mon Sep 17 00:00:00 2001 From: ErikEk Date: Fri, 6 May 2022 21:40:36 +0200 Subject: [PATCH] neutrinorpc: add getblockhash functionality --- lnrpc/neutrinorpc/neutrino.pb.go | 227 ++++++++++++++++++----- lnrpc/neutrinorpc/neutrino.pb.gw.go | 99 ++++++++++ lnrpc/neutrinorpc/neutrino.proto | 17 +- lnrpc/neutrinorpc/neutrino.swagger.json | 42 +++++ lnrpc/neutrinorpc/neutrino.yaml | 4 +- lnrpc/neutrinorpc/neutrino_grpc.pb.go | 40 ++++ lnrpc/neutrinorpc/neutrino_server.go | 71 ++++--- lnrpc/neutrinorpc/neutrinokit.pb.json.go | 25 +++ 8 files changed, 452 insertions(+), 73 deletions(-) diff --git a/lnrpc/neutrinorpc/neutrino.pb.go b/lnrpc/neutrinorpc/neutrino.pb.go index 7395197ce..7ccfbbf1e 100644 --- a/lnrpc/neutrinorpc/neutrino.pb.go +++ b/lnrpc/neutrinorpc/neutrino.pb.go @@ -958,6 +958,102 @@ func (x *GetCFilterResponse) GetFilter() []byte { return nil } +type GetBlockHashRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // The block height or index. + Height int32 `protobuf:"varint,1,opt,name=height,proto3" json:"height,omitempty"` +} + +func (x *GetBlockHashRequest) Reset() { + *x = GetBlockHashRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_neutrinorpc_neutrino_proto_msgTypes[14] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetBlockHashRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetBlockHashRequest) ProtoMessage() {} + +func (x *GetBlockHashRequest) ProtoReflect() protoreflect.Message { + mi := &file_neutrinorpc_neutrino_proto_msgTypes[14] + 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 GetBlockHashRequest.ProtoReflect.Descriptor instead. +func (*GetBlockHashRequest) Descriptor() ([]byte, []int) { + return file_neutrinorpc_neutrino_proto_rawDescGZIP(), []int{14} +} + +func (x *GetBlockHashRequest) GetHeight() int32 { + if x != nil { + return x.Height + } + return 0 +} + +type GetBlockHashResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // The block hash. + Hash string `protobuf:"bytes,1,opt,name=hash,proto3" json:"hash,omitempty"` +} + +func (x *GetBlockHashResponse) Reset() { + *x = GetBlockHashResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_neutrinorpc_neutrino_proto_msgTypes[15] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetBlockHashResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetBlockHashResponse) ProtoMessage() {} + +func (x *GetBlockHashResponse) ProtoReflect() protoreflect.Message { + mi := &file_neutrinorpc_neutrino_proto_msgTypes[15] + 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 GetBlockHashResponse.ProtoReflect.Descriptor instead. +func (*GetBlockHashResponse) Descriptor() ([]byte, []int) { + return file_neutrinorpc_neutrino_proto_rawDescGZIP(), []int{15} +} + +func (x *GetBlockHashResponse) GetHash() string { + if x != nil { + return x.Hash + } + return "" +} + var File_neutrinorpc_neutrino_proto protoreflect.FileDescriptor var file_neutrinorpc_neutrino_proto_rawDesc = []byte{ @@ -1055,41 +1151,52 @@ var file_neutrinorpc_neutrino_proto_rawDesc = []byte{ 0x68, 0x61, 0x73, 0x68, 0x22, 0x2c, 0x0a, 0x12, 0x47, 0x65, 0x74, 0x43, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x66, 0x69, 0x6c, 0x74, - 0x65, 0x72, 0x32, 0xad, 0x04, 0x0a, 0x0b, 0x4e, 0x65, 0x75, 0x74, 0x72, 0x69, 0x6e, 0x6f, 0x4b, - 0x69, 0x74, 0x12, 0x41, 0x0a, 0x06, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x1a, 0x2e, 0x6e, - 0x65, 0x75, 0x74, 0x72, 0x69, 0x6e, 0x6f, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, - 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1b, 0x2e, 0x6e, 0x65, 0x75, 0x74, 0x72, - 0x69, 0x6e, 0x6f, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x44, 0x0a, 0x07, 0x41, 0x64, 0x64, 0x50, 0x65, 0x65, 0x72, - 0x12, 0x1b, 0x2e, 0x6e, 0x65, 0x75, 0x74, 0x72, 0x69, 0x6e, 0x6f, 0x72, 0x70, 0x63, 0x2e, 0x41, - 0x64, 0x64, 0x50, 0x65, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1c, 0x2e, - 0x6e, 0x65, 0x75, 0x74, 0x72, 0x69, 0x6e, 0x6f, 0x72, 0x70, 0x63, 0x2e, 0x41, 0x64, 0x64, 0x50, - 0x65, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x59, 0x0a, 0x0e, 0x44, - 0x69, 0x73, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x50, 0x65, 0x65, 0x72, 0x12, 0x22, 0x2e, - 0x6e, 0x65, 0x75, 0x74, 0x72, 0x69, 0x6e, 0x6f, 0x72, 0x70, 0x63, 0x2e, 0x44, 0x69, 0x73, 0x63, - 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x50, 0x65, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x1a, 0x23, 0x2e, 0x6e, 0x65, 0x75, 0x74, 0x72, 0x69, 0x6e, 0x6f, 0x72, 0x70, 0x63, 0x2e, - 0x44, 0x69, 0x73, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x50, 0x65, 0x65, 0x72, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x47, 0x0a, 0x08, 0x49, 0x73, 0x42, 0x61, 0x6e, 0x6e, - 0x65, 0x64, 0x12, 0x1c, 0x2e, 0x6e, 0x65, 0x75, 0x74, 0x72, 0x69, 0x6e, 0x6f, 0x72, 0x70, 0x63, - 0x2e, 0x49, 0x73, 0x42, 0x61, 0x6e, 0x6e, 0x65, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x1a, 0x1d, 0x2e, 0x6e, 0x65, 0x75, 0x74, 0x72, 0x69, 0x6e, 0x6f, 0x72, 0x70, 0x63, 0x2e, 0x49, - 0x73, 0x42, 0x61, 0x6e, 0x6e, 0x65, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, - 0x59, 0x0a, 0x0e, 0x47, 0x65, 0x74, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x48, 0x65, 0x61, 0x64, 0x65, - 0x72, 0x12, 0x22, 0x2e, 0x6e, 0x65, 0x75, 0x74, 0x72, 0x69, 0x6e, 0x6f, 0x72, 0x70, 0x63, 0x2e, - 0x47, 0x65, 0x74, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x23, 0x2e, 0x6e, 0x65, 0x75, 0x74, 0x72, 0x69, 0x6e, 0x6f, - 0x72, 0x70, 0x63, 0x2e, 0x47, 0x65, 0x74, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x48, 0x65, 0x61, 0x64, - 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x47, 0x0a, 0x08, 0x47, 0x65, - 0x74, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x12, 0x1c, 0x2e, 0x6e, 0x65, 0x75, 0x74, 0x72, 0x69, 0x6e, - 0x6f, 0x72, 0x70, 0x63, 0x2e, 0x47, 0x65, 0x74, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x6e, 0x65, 0x75, 0x74, 0x72, 0x69, 0x6e, 0x6f, 0x72, - 0x70, 0x63, 0x2e, 0x47, 0x65, 0x74, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x12, 0x4d, 0x0a, 0x0a, 0x47, 0x65, 0x74, 0x43, 0x46, 0x69, 0x6c, 0x74, 0x65, - 0x72, 0x12, 0x1e, 0x2e, 0x6e, 0x65, 0x75, 0x74, 0x72, 0x69, 0x6e, 0x6f, 0x72, 0x70, 0x63, 0x2e, - 0x47, 0x65, 0x74, 0x43, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x1a, 0x1f, 0x2e, 0x6e, 0x65, 0x75, 0x74, 0x72, 0x69, 0x6e, 0x6f, 0x72, 0x70, 0x63, 0x2e, - 0x47, 0x65, 0x74, 0x43, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x65, 0x72, 0x22, 0x2d, 0x0a, 0x13, 0x47, 0x65, 0x74, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x48, 0x61, + 0x73, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x68, 0x65, 0x69, + 0x67, 0x68, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x06, 0x68, 0x65, 0x69, 0x67, 0x68, + 0x74, 0x22, 0x2a, 0x0a, 0x14, 0x47, 0x65, 0x74, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x48, 0x61, 0x73, + 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x68, 0x61, 0x73, + 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x68, 0x61, 0x73, 0x68, 0x32, 0x82, 0x05, + 0x0a, 0x0b, 0x4e, 0x65, 0x75, 0x74, 0x72, 0x69, 0x6e, 0x6f, 0x4b, 0x69, 0x74, 0x12, 0x41, 0x0a, + 0x06, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x1a, 0x2e, 0x6e, 0x65, 0x75, 0x74, 0x72, 0x69, + 0x6e, 0x6f, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x1a, 0x1b, 0x2e, 0x6e, 0x65, 0x75, 0x74, 0x72, 0x69, 0x6e, 0x6f, 0x72, 0x70, + 0x63, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x12, 0x44, 0x0a, 0x07, 0x41, 0x64, 0x64, 0x50, 0x65, 0x65, 0x72, 0x12, 0x1b, 0x2e, 0x6e, 0x65, + 0x75, 0x74, 0x72, 0x69, 0x6e, 0x6f, 0x72, 0x70, 0x63, 0x2e, 0x41, 0x64, 0x64, 0x50, 0x65, 0x65, + 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1c, 0x2e, 0x6e, 0x65, 0x75, 0x74, 0x72, + 0x69, 0x6e, 0x6f, 0x72, 0x70, 0x63, 0x2e, 0x41, 0x64, 0x64, 0x50, 0x65, 0x65, 0x72, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x59, 0x0a, 0x0e, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x6e, + 0x6e, 0x65, 0x63, 0x74, 0x50, 0x65, 0x65, 0x72, 0x12, 0x22, 0x2e, 0x6e, 0x65, 0x75, 0x74, 0x72, + 0x69, 0x6e, 0x6f, 0x72, 0x70, 0x63, 0x2e, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, + 0x74, 0x50, 0x65, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x23, 0x2e, 0x6e, + 0x65, 0x75, 0x74, 0x72, 0x69, 0x6e, 0x6f, 0x72, 0x70, 0x63, 0x2e, 0x44, 0x69, 0x73, 0x63, 0x6f, + 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x50, 0x65, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x12, 0x47, 0x0a, 0x08, 0x49, 0x73, 0x42, 0x61, 0x6e, 0x6e, 0x65, 0x64, 0x12, 0x1c, 0x2e, + 0x6e, 0x65, 0x75, 0x74, 0x72, 0x69, 0x6e, 0x6f, 0x72, 0x70, 0x63, 0x2e, 0x49, 0x73, 0x42, 0x61, + 0x6e, 0x6e, 0x65, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x6e, 0x65, + 0x75, 0x74, 0x72, 0x69, 0x6e, 0x6f, 0x72, 0x70, 0x63, 0x2e, 0x49, 0x73, 0x42, 0x61, 0x6e, 0x6e, + 0x65, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x59, 0x0a, 0x0e, 0x47, 0x65, + 0x74, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x12, 0x22, 0x2e, 0x6e, + 0x65, 0x75, 0x74, 0x72, 0x69, 0x6e, 0x6f, 0x72, 0x70, 0x63, 0x2e, 0x47, 0x65, 0x74, 0x42, 0x6c, + 0x6f, 0x63, 0x6b, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x1a, 0x23, 0x2e, 0x6e, 0x65, 0x75, 0x74, 0x72, 0x69, 0x6e, 0x6f, 0x72, 0x70, 0x63, 0x2e, 0x47, + 0x65, 0x74, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x47, 0x0a, 0x08, 0x47, 0x65, 0x74, 0x42, 0x6c, 0x6f, 0x63, + 0x6b, 0x12, 0x1c, 0x2e, 0x6e, 0x65, 0x75, 0x74, 0x72, 0x69, 0x6e, 0x6f, 0x72, 0x70, 0x63, 0x2e, + 0x47, 0x65, 0x74, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x1d, 0x2e, 0x6e, 0x65, 0x75, 0x74, 0x72, 0x69, 0x6e, 0x6f, 0x72, 0x70, 0x63, 0x2e, 0x47, 0x65, + 0x74, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4d, + 0x0a, 0x0a, 0x47, 0x65, 0x74, 0x43, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x12, 0x1e, 0x2e, 0x6e, + 0x65, 0x75, 0x74, 0x72, 0x69, 0x6e, 0x6f, 0x72, 0x70, 0x63, 0x2e, 0x47, 0x65, 0x74, 0x43, 0x46, + 0x69, 0x6c, 0x74, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f, 0x2e, 0x6e, + 0x65, 0x75, 0x74, 0x72, 0x69, 0x6e, 0x6f, 0x72, 0x70, 0x63, 0x2e, 0x47, 0x65, 0x74, 0x43, 0x46, + 0x69, 0x6c, 0x74, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x53, 0x0a, + 0x0c, 0x47, 0x65, 0x74, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x48, 0x61, 0x73, 0x68, 0x12, 0x20, 0x2e, + 0x6e, 0x65, 0x75, 0x74, 0x72, 0x69, 0x6e, 0x6f, 0x72, 0x70, 0x63, 0x2e, 0x47, 0x65, 0x74, 0x42, + 0x6c, 0x6f, 0x63, 0x6b, 0x48, 0x61, 0x73, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x21, 0x2e, 0x6e, 0x65, 0x75, 0x74, 0x72, 0x69, 0x6e, 0x6f, 0x72, 0x70, 0x63, 0x2e, 0x47, 0x65, + 0x74, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x48, 0x61, 0x73, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x33, 0x5a, 0x31, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6c, 0x69, 0x67, 0x68, 0x74, 0x6e, 0x69, 0x6e, 0x67, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x2f, 0x6c, 0x6e, 0x64, 0x2f, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2f, 0x6e, 0x65, 0x75, 0x74, @@ -1108,7 +1215,7 @@ func file_neutrinorpc_neutrino_proto_rawDescGZIP() []byte { return file_neutrinorpc_neutrino_proto_rawDescData } -var file_neutrinorpc_neutrino_proto_msgTypes = make([]protoimpl.MessageInfo, 14) +var file_neutrinorpc_neutrino_proto_msgTypes = make([]protoimpl.MessageInfo, 16) var file_neutrinorpc_neutrino_proto_goTypes = []interface{}{ (*StatusRequest)(nil), // 0: neutrinorpc.StatusRequest (*StatusResponse)(nil), // 1: neutrinorpc.StatusResponse @@ -1124,6 +1231,8 @@ var file_neutrinorpc_neutrino_proto_goTypes = []interface{}{ (*GetBlockResponse)(nil), // 11: neutrinorpc.GetBlockResponse (*GetCFilterRequest)(nil), // 12: neutrinorpc.GetCFilterRequest (*GetCFilterResponse)(nil), // 13: neutrinorpc.GetCFilterResponse + (*GetBlockHashRequest)(nil), // 14: neutrinorpc.GetBlockHashRequest + (*GetBlockHashResponse)(nil), // 15: neutrinorpc.GetBlockHashResponse } var file_neutrinorpc_neutrino_proto_depIdxs = []int32{ 0, // 0: neutrinorpc.NeutrinoKit.Status:input_type -> neutrinorpc.StatusRequest @@ -1133,15 +1242,17 @@ var file_neutrinorpc_neutrino_proto_depIdxs = []int32{ 8, // 4: neutrinorpc.NeutrinoKit.GetBlockHeader:input_type -> neutrinorpc.GetBlockHeaderRequest 10, // 5: neutrinorpc.NeutrinoKit.GetBlock:input_type -> neutrinorpc.GetBlockRequest 12, // 6: neutrinorpc.NeutrinoKit.GetCFilter:input_type -> neutrinorpc.GetCFilterRequest - 1, // 7: neutrinorpc.NeutrinoKit.Status:output_type -> neutrinorpc.StatusResponse - 3, // 8: neutrinorpc.NeutrinoKit.AddPeer:output_type -> neutrinorpc.AddPeerResponse - 5, // 9: neutrinorpc.NeutrinoKit.DisconnectPeer:output_type -> neutrinorpc.DisconnectPeerResponse - 7, // 10: neutrinorpc.NeutrinoKit.IsBanned:output_type -> neutrinorpc.IsBannedResponse - 9, // 11: neutrinorpc.NeutrinoKit.GetBlockHeader:output_type -> neutrinorpc.GetBlockHeaderResponse - 11, // 12: neutrinorpc.NeutrinoKit.GetBlock:output_type -> neutrinorpc.GetBlockResponse - 13, // 13: neutrinorpc.NeutrinoKit.GetCFilter:output_type -> neutrinorpc.GetCFilterResponse - 7, // [7:14] is the sub-list for method output_type - 0, // [0:7] is the sub-list for method input_type + 14, // 7: neutrinorpc.NeutrinoKit.GetBlockHash:input_type -> neutrinorpc.GetBlockHashRequest + 1, // 8: neutrinorpc.NeutrinoKit.Status:output_type -> neutrinorpc.StatusResponse + 3, // 9: neutrinorpc.NeutrinoKit.AddPeer:output_type -> neutrinorpc.AddPeerResponse + 5, // 10: neutrinorpc.NeutrinoKit.DisconnectPeer:output_type -> neutrinorpc.DisconnectPeerResponse + 7, // 11: neutrinorpc.NeutrinoKit.IsBanned:output_type -> neutrinorpc.IsBannedResponse + 9, // 12: neutrinorpc.NeutrinoKit.GetBlockHeader:output_type -> neutrinorpc.GetBlockHeaderResponse + 11, // 13: neutrinorpc.NeutrinoKit.GetBlock:output_type -> neutrinorpc.GetBlockResponse + 13, // 14: neutrinorpc.NeutrinoKit.GetCFilter:output_type -> neutrinorpc.GetCFilterResponse + 15, // 15: neutrinorpc.NeutrinoKit.GetBlockHash:output_type -> neutrinorpc.GetBlockHashResponse + 8, // [8:16] is the sub-list for method output_type + 0, // [0:8] is the sub-list for method input_type 0, // [0:0] is the sub-list for extension type_name 0, // [0:0] is the sub-list for extension extendee 0, // [0:0] is the sub-list for field type_name @@ -1321,6 +1432,30 @@ func file_neutrinorpc_neutrino_proto_init() { return nil } } + file_neutrinorpc_neutrino_proto_msgTypes[14].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetBlockHashRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_neutrinorpc_neutrino_proto_msgTypes[15].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetBlockHashResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } } type x struct{} out := protoimpl.TypeBuilder{ @@ -1328,7 +1463,7 @@ func file_neutrinorpc_neutrino_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_neutrinorpc_neutrino_proto_rawDesc, NumEnums: 0, - NumMessages: 14, + NumMessages: 16, NumExtensions: 0, NumServices: 1, }, diff --git a/lnrpc/neutrinorpc/neutrino.pb.gw.go b/lnrpc/neutrinorpc/neutrino.pb.gw.go index 7c10a3a03..0d5320398 100644 --- a/lnrpc/neutrinorpc/neutrino.pb.gw.go +++ b/lnrpc/neutrinorpc/neutrino.pb.gw.go @@ -309,6 +309,58 @@ func local_request_NeutrinoKit_GetCFilter_0(ctx context.Context, marshaler runti } +func request_NeutrinoKit_GetBlockHash_0(ctx context.Context, marshaler runtime.Marshaler, client NeutrinoKitClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq GetBlockHashRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["height"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "height") + } + + protoReq.Height, err = runtime.Int32(val) + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "height", err) + } + + msg, err := client.GetBlockHash(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_NeutrinoKit_GetBlockHash_0(ctx context.Context, marshaler runtime.Marshaler, server NeutrinoKitServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq GetBlockHashRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["height"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "height") + } + + protoReq.Height, err = runtime.Int32(val) + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "height", err) + } + + msg, err := server.GetBlockHash(ctx, &protoReq) + return msg, metadata, err + +} + // RegisterNeutrinoKitHandlerServer registers the http handlers for service NeutrinoKit to "mux". // UnaryRPC :call NeutrinoKitServer directly. // StreamingRPC :currently unsupported pending https://github.com/grpc/grpc-go/issues/906. @@ -476,6 +528,29 @@ func RegisterNeutrinoKitHandlerServer(ctx context.Context, mux *runtime.ServeMux }) + mux.Handle("GET", pattern_NeutrinoKit_GetBlockHash_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/neutrinorpc.NeutrinoKit/GetBlockHash", runtime.WithHTTPPathPattern("/v2/neutrino/blockhash/{height}")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_NeutrinoKit_GetBlockHash_0(rctx, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_NeutrinoKit_GetBlockHash_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + return nil } @@ -657,6 +732,26 @@ func RegisterNeutrinoKitHandlerClient(ctx context.Context, mux *runtime.ServeMux }) + mux.Handle("GET", pattern_NeutrinoKit_GetBlockHash_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateContext(ctx, mux, req, "/neutrinorpc.NeutrinoKit/GetBlockHash", runtime.WithHTTPPathPattern("/v2/neutrino/blockhash/{height}")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_NeutrinoKit_GetBlockHash_0(rctx, inboundMarshaler, client, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_NeutrinoKit_GetBlockHash_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + return nil } @@ -674,6 +769,8 @@ var ( pattern_NeutrinoKit_GetBlock_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 1, 5, 3}, []string{"v2", "neutrino", "block", "hash"}, "")) pattern_NeutrinoKit_GetCFilter_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 1, 5, 3}, []string{"v2", "neutrino", "cfilter", "hash"}, "")) + + pattern_NeutrinoKit_GetBlockHash_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 1, 5, 3}, []string{"v2", "neutrino", "blockhash", "height"}, "")) ) var ( @@ -690,4 +787,6 @@ var ( forward_NeutrinoKit_GetBlock_0 = runtime.ForwardResponseMessage forward_NeutrinoKit_GetCFilter_0 = runtime.ForwardResponseMessage + + forward_NeutrinoKit_GetBlockHash_0 = runtime.ForwardResponseMessage ) diff --git a/lnrpc/neutrinorpc/neutrino.proto b/lnrpc/neutrinorpc/neutrino.proto index 388714813..a82bd2276 100644 --- a/lnrpc/neutrinorpc/neutrino.proto +++ b/lnrpc/neutrinorpc/neutrino.proto @@ -45,6 +45,11 @@ service NeutrinoKit { GetCFilter returns a compact filter from a block. */ rpc GetCFilter (GetCFilterRequest) returns (GetCFilterResponse); + + /* + GetBlockHash returns the header hash of a block at a given height. + */ + rpc GetBlockHash (GetBlockHashRequest) returns (GetBlockHashResponse); } message StatusRequest { @@ -207,4 +212,14 @@ message GetCFilterRequest { message GetCFilterResponse { // GCS filter. bytes filter = 1; -} \ No newline at end of file +} + +message GetBlockHashRequest { + // The block height or index. + int32 height = 1; +} + +message GetBlockHashResponse { + // The block hash. + string hash = 1; +} diff --git a/lnrpc/neutrinorpc/neutrino.swagger.json b/lnrpc/neutrinorpc/neutrino.swagger.json index 5be08ef01..a8b344601 100644 --- a/lnrpc/neutrinorpc/neutrino.swagger.json +++ b/lnrpc/neutrinorpc/neutrino.swagger.json @@ -81,6 +81,39 @@ ] } }, + "/v2/neutrino/blockhash/{height}": { + "get": { + "summary": "GetBlockHash returns the header hash of a block at a given height.", + "operationId": "NeutrinoKit_GetBlockHash", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/neutrinorpcGetBlockHashResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "height", + "description": "The block height or index.", + "in": "path", + "required": true, + "type": "integer", + "format": "int32" + } + ], + "tags": [ + "NeutrinoKit" + ] + } + }, "/v2/neutrino/blockheader/{hash}": { "get": { "summary": "GetBlockHeader returns a block header with a particular block hash.", @@ -259,6 +292,15 @@ "neutrinorpcDisconnectPeerResponse": { "type": "object" }, + "neutrinorpcGetBlockHashResponse": { + "type": "object", + "properties": { + "hash": { + "type": "string", + "description": "The block hash." + } + } + }, "neutrinorpcGetBlockHeaderResponse": { "type": "object", "properties": { diff --git a/lnrpc/neutrinorpc/neutrino.yaml b/lnrpc/neutrinorpc/neutrino.yaml index d8547b7e5..c81ef700e 100644 --- a/lnrpc/neutrinorpc/neutrino.yaml +++ b/lnrpc/neutrinorpc/neutrino.yaml @@ -18,4 +18,6 @@ http: - selector: neutrinorpc.NeutrinoKit.GetBlockHeader get: "/v2/neutrino/blockheader/{hash}" - selector: neutrinorpc.NeutrinoKit.GetCFilter - get: "/v2/neutrino/cfilter/{hash}" \ No newline at end of file + get: "/v2/neutrino/cfilter/{hash}" + - selector: neutrinorpc.NeutrinoKit.GetBlockHash + get: "/v2/neutrino/blockhash/{height}" diff --git a/lnrpc/neutrinorpc/neutrino_grpc.pb.go b/lnrpc/neutrinorpc/neutrino_grpc.pb.go index 2003cfb52..889057069 100644 --- a/lnrpc/neutrinorpc/neutrino_grpc.pb.go +++ b/lnrpc/neutrinorpc/neutrino_grpc.pb.go @@ -43,6 +43,9 @@ type NeutrinoKitClient interface { // //GetCFilter returns a compact filter from a block. GetCFilter(ctx context.Context, in *GetCFilterRequest, opts ...grpc.CallOption) (*GetCFilterResponse, error) + // + //GetBlockHash returns the header hash of a block at a given height. + GetBlockHash(ctx context.Context, in *GetBlockHashRequest, opts ...grpc.CallOption) (*GetBlockHashResponse, error) } type neutrinoKitClient struct { @@ -116,6 +119,15 @@ func (c *neutrinoKitClient) GetCFilter(ctx context.Context, in *GetCFilterReques return out, nil } +func (c *neutrinoKitClient) GetBlockHash(ctx context.Context, in *GetBlockHashRequest, opts ...grpc.CallOption) (*GetBlockHashResponse, error) { + out := new(GetBlockHashResponse) + err := c.cc.Invoke(ctx, "/neutrinorpc.NeutrinoKit/GetBlockHash", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + // NeutrinoKitServer is the server API for NeutrinoKit service. // All implementations must embed UnimplementedNeutrinoKitServer // for forward compatibility @@ -145,6 +157,9 @@ type NeutrinoKitServer interface { // //GetCFilter returns a compact filter from a block. GetCFilter(context.Context, *GetCFilterRequest) (*GetCFilterResponse, error) + // + //GetBlockHash returns the header hash of a block at a given height. + GetBlockHash(context.Context, *GetBlockHashRequest) (*GetBlockHashResponse, error) mustEmbedUnimplementedNeutrinoKitServer() } @@ -173,6 +188,9 @@ func (UnimplementedNeutrinoKitServer) GetBlock(context.Context, *GetBlockRequest func (UnimplementedNeutrinoKitServer) GetCFilter(context.Context, *GetCFilterRequest) (*GetCFilterResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method GetCFilter not implemented") } +func (UnimplementedNeutrinoKitServer) GetBlockHash(context.Context, *GetBlockHashRequest) (*GetBlockHashResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetBlockHash not implemented") +} func (UnimplementedNeutrinoKitServer) mustEmbedUnimplementedNeutrinoKitServer() {} // UnsafeNeutrinoKitServer may be embedded to opt out of forward compatibility for this service. @@ -312,6 +330,24 @@ func _NeutrinoKit_GetCFilter_Handler(srv interface{}, ctx context.Context, dec f return interceptor(ctx, in, info, handler) } +func _NeutrinoKit_GetBlockHash_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GetBlockHashRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(NeutrinoKitServer).GetBlockHash(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/neutrinorpc.NeutrinoKit/GetBlockHash", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(NeutrinoKitServer).GetBlockHash(ctx, req.(*GetBlockHashRequest)) + } + return interceptor(ctx, in, info, handler) +} + // NeutrinoKit_ServiceDesc is the grpc.ServiceDesc for NeutrinoKit service. // It's only intended for direct use with grpc.RegisterService, // and not to be introspected or modified (even as a copy) @@ -347,6 +383,10 @@ var NeutrinoKit_ServiceDesc = grpc.ServiceDesc{ MethodName: "GetCFilter", Handler: _NeutrinoKit_GetCFilter_Handler, }, + { + MethodName: "GetBlockHash", + Handler: _NeutrinoKit_GetBlockHash_Handler, + }, }, Streams: []grpc.StreamDesc{}, Metadata: "neutrinorpc/neutrino.proto", diff --git a/lnrpc/neutrinorpc/neutrino_server.go b/lnrpc/neutrinorpc/neutrino_server.go index fdfbe64c5..1948c5d1e 100644 --- a/lnrpc/neutrinorpc/neutrino_server.go +++ b/lnrpc/neutrinorpc/neutrino_server.go @@ -59,6 +59,10 @@ var ( Entity: "onchain", Action: "read", }}, + "/neutrinorpc.NeutrinoKit/GetBlockHash": {{ + Entity: "onchain", + Action: "read", + }}, } // ErrNeutrinoNotActive is an error returned when there is no running @@ -192,13 +196,12 @@ func (s *Server) Status(ctx context.Context, in *StatusRequest) (*StatusResponse, error) { if s.cfg.NeutrinoCS == nil { - return &StatusResponse{}, nil + return nil, ErrNeutrinoNotActive } bestBlock, err := s.cfg.NeutrinoCS.BestBlock() if err != nil { - return &StatusResponse{}, - fmt.Errorf("could not get best block: %v", err) + return nil, fmt.Errorf("could not get best block: %v", err) } peers := s.cfg.NeutrinoCS.Peers() @@ -223,12 +226,12 @@ func (s *Server) AddPeer(ctx context.Context, in *AddPeerRequest) (*AddPeerResponse, error) { if s.cfg.NeutrinoCS == nil { - return &AddPeerResponse{}, ErrNeutrinoNotActive + return nil, ErrNeutrinoNotActive } peer := s.cfg.NeutrinoCS.PeerByAddr(in.PeerAddrs) if peer == nil { - return &AddPeerResponse{}, + return nil, fmt.Errorf("could not found peer: %s", in.PeerAddrs) } s.cfg.NeutrinoCS.AddPeer(peer) @@ -245,18 +248,18 @@ func (s *Server) DisconnectPeer(ctx context.Context, in *DisconnectPeerRequest) (*DisconnectPeerResponse, error) { if s.cfg.NeutrinoCS == nil { - return &DisconnectPeerResponse{}, ErrNeutrinoNotActive + return nil, ErrNeutrinoNotActive } peer := s.cfg.NeutrinoCS.PeerByAddr(in.PeerAddrs) if peer == nil { - return &DisconnectPeerResponse{}, + return nil, fmt.Errorf("could not found peer: %s", in.PeerAddrs) } err := s.cfg.NeutrinoCS.DisconnectNodeByAddr(peer.Addr()) if err != nil { - return &DisconnectPeerResponse{}, err + return nil, err } return &DisconnectPeerResponse{}, nil @@ -269,7 +272,7 @@ func (s *Server) IsBanned(ctx context.Context, in *IsBannedRequest) (*IsBannedResponse, error) { if s.cfg.NeutrinoCS == nil { - return &IsBannedResponse{}, ErrNeutrinoNotActive + return nil, ErrNeutrinoNotActive } return &IsBannedResponse{ @@ -287,17 +290,17 @@ func (s *Server) GetBlockHeader(ctx context.Context, in *GetBlockHeaderRequest) (*GetBlockHeaderResponse, error) { if s.cfg.NeutrinoCS == nil { - return &GetBlockHeaderResponse{}, ErrNeutrinoNotActive + return nil, ErrNeutrinoNotActive } var hash chainhash.Hash if err := chainhash.Decode(&hash, in.Hash); err != nil { - return &GetBlockHeaderResponse{}, err + return nil, err } resp, err := s.getBlock(hash) if err != nil { - return &GetBlockHeaderResponse{}, err + return nil, err } return &GetBlockHeaderResponse{ @@ -328,12 +331,12 @@ func (s *Server) GetBlock(ctx context.Context, in *GetBlockRequest) (*GetBlockResponse, error) { if s.cfg.NeutrinoCS == nil { - return &GetBlockResponse{}, ErrNeutrinoNotActive + return nil, ErrNeutrinoNotActive } var hash chainhash.Hash if err := chainhash.Decode(&hash, in.Hash); err != nil { - return &GetBlockResponse{}, err + return nil, err } return s.getBlock(hash) @@ -347,24 +350,24 @@ func (s *Server) GetCFilter(ctx context.Context, in *GetCFilterRequest) (*GetCFilterResponse, error) { if s.cfg.NeutrinoCS == nil { - return &GetCFilterResponse{}, ErrNeutrinoNotActive + return nil, ErrNeutrinoNotActive } var hash chainhash.Hash if err := chainhash.Decode(&hash, in.Hash); err != nil { - return &GetCFilterResponse{}, err + return nil, err } - // GetCFilter returns a compact filter from the database. If it is missing, - // it requests the compact filter from the network. + // GetCFilter returns a compact filter from the database. If it is + // missing, it requests the compact filter from the network. filter, err := s.cfg.NeutrinoCS.GetCFilter(hash, wire.GCSFilterRegular) if err != nil { - return &GetCFilterResponse{}, err + return nil, err } filterlBytes, err := filter.Bytes() if err != nil { - return &GetCFilterResponse{}, err + return nil, err } return &GetCFilterResponse{Filter: filterlBytes}, nil @@ -373,27 +376,27 @@ func (s *Server) GetCFilter(ctx context.Context, func (s *Server) getBlock(hash chainhash.Hash) (*GetBlockResponse, error) { block, err := s.cfg.NeutrinoCS.GetBlock(hash) if err != nil { - return &GetBlockResponse{}, err + return nil, err } header, _, err := s.cfg.NeutrinoCS.BlockHeaders.FetchHeader(&hash) if err != nil { - return &GetBlockResponse{}, err + return nil, err } blockData, err := block.Bytes() if err != nil { - return &GetBlockResponse{}, err + return nil, err } strippedData, err := block.BytesNoWitness() if err != nil { - return &GetBlockResponse{}, err + return nil, err } bestBlock, err := s.cfg.NeutrinoCS.BestBlock() if err != nil { - return &GetBlockResponse{}, err + return nil, err } // Convert txids to a string array. @@ -423,3 +426,21 @@ func (s *Server) getBlock(hash chainhash.Hash) (*GetBlockResponse, error) { RawHex: blockData, }, nil } + +// GetBlockHash returns the header hash of a block at a given height. +// +// NOTE: Part of the NeutrinoKitServer interface. +func (s *Server) GetBlockHash(ctx context.Context, + in *GetBlockHashRequest) (*GetBlockHashResponse, error) { + + if s.cfg.NeutrinoCS == nil { + return nil, ErrNeutrinoNotActive + } + + hash, err := s.cfg.NeutrinoCS.GetBlockHash(int64(in.Height)) + if err != nil { + return nil, err + } + + return &GetBlockHashResponse{Hash: hash.String()}, nil +} diff --git a/lnrpc/neutrinorpc/neutrinokit.pb.json.go b/lnrpc/neutrinorpc/neutrinokit.pb.json.go index 2b9e2664e..5c5ee453b 100644 --- a/lnrpc/neutrinorpc/neutrinokit.pb.json.go +++ b/lnrpc/neutrinorpc/neutrinokit.pb.json.go @@ -197,4 +197,29 @@ func RegisterNeutrinoKitJSONCallbacks(registry map[string]func(ctx context.Conte } callback(string(respBytes), nil) } + + registry["neutrinorpc.NeutrinoKit.GetBlockHash"] = func(ctx context.Context, + conn *grpc.ClientConn, reqJSON string, callback func(string, error)) { + + req := &GetBlockHashRequest{} + err := marshaler.Unmarshal([]byte(reqJSON), req) + if err != nil { + callback("", err) + return + } + + client := NewNeutrinoKitClient(conn) + resp, err := client.GetBlockHash(ctx, req) + if err != nil { + callback("", err) + return + } + + respBytes, err := marshaler.Marshal(resp) + if err != nil { + callback("", err) + return + } + callback(string(respBytes), nil) + } }