From 92e35bd23a950a0545c3a869f33d4ea4b2d4c043 Mon Sep 17 00:00:00 2001 From: Alex Grintsvayg Date: Thu, 25 Oct 2018 14:20:21 -0400 Subject: [PATCH] blobex draft --- blobex/blobex.pb.go | 756 ++++++++++++++++++++++++++++++++++++++++++++ blobex/blobex.proto | 86 +++++ blobex/proto.sh | 29 ++ blobex/server.go | 49 +++ 4 files changed, 920 insertions(+) create mode 100644 blobex/blobex.pb.go create mode 100644 blobex/blobex.proto create mode 100755 blobex/proto.sh create mode 100644 blobex/server.go diff --git a/blobex/blobex.pb.go b/blobex/blobex.pb.go new file mode 100644 index 0000000..ae7f52e --- /dev/null +++ b/blobex/blobex.pb.go @@ -0,0 +1,756 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// source: blobex.proto + +package blobex + +import ( + fmt "fmt" + proto "github.com/golang/protobuf/proto" + math "math" +) + +import ( + context "golang.org/x/net/context" + grpc "google.golang.org/grpc" +) + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package + +type Error struct { + // should we enum the error codes? + Code uint32 `protobuf:"varint,1,opt,name=code,proto3" json:"code,omitempty"` + Message string `protobuf:"bytes,2,opt,name=message,proto3" json:"message,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *Error) Reset() { *m = Error{} } +func (m *Error) String() string { return proto.CompactTextString(m) } +func (*Error) ProtoMessage() {} +func (*Error) Descriptor() ([]byte, []int) { + return fileDescriptor_183aee39e18f30c9, []int{0} +} + +func (m *Error) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_Error.Unmarshal(m, b) +} +func (m *Error) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_Error.Marshal(b, m, deterministic) +} +func (m *Error) XXX_Merge(src proto.Message) { + xxx_messageInfo_Error.Merge(m, src) +} +func (m *Error) XXX_Size() int { + return xxx_messageInfo_Error.Size(m) +} +func (m *Error) XXX_DiscardUnknown() { + xxx_messageInfo_Error.DiscardUnknown(m) +} + +var xxx_messageInfo_Error proto.InternalMessageInfo + +func (m *Error) GetCode() uint32 { + if m != nil { + return m.Code + } + return 0 +} + +func (m *Error) GetMessage() string { + if m != nil { + return m.Message + } + return "" +} + +// how much does the host charge per kb at the moment +type PriceCheckRequest struct { + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *PriceCheckRequest) Reset() { *m = PriceCheckRequest{} } +func (m *PriceCheckRequest) String() string { return proto.CompactTextString(m) } +func (*PriceCheckRequest) ProtoMessage() {} +func (*PriceCheckRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_183aee39e18f30c9, []int{1} +} + +func (m *PriceCheckRequest) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_PriceCheckRequest.Unmarshal(m, b) +} +func (m *PriceCheckRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_PriceCheckRequest.Marshal(b, m, deterministic) +} +func (m *PriceCheckRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_PriceCheckRequest.Merge(m, src) +} +func (m *PriceCheckRequest) XXX_Size() int { + return xxx_messageInfo_PriceCheckRequest.Size(m) +} +func (m *PriceCheckRequest) XXX_DiscardUnknown() { + xxx_messageInfo_PriceCheckRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_PriceCheckRequest proto.InternalMessageInfo + +type PriceCheckResponse struct { + Error *Error `protobuf:"bytes,1,opt,name=error,proto3" json:"error,omitempty"` + DeweysPerKB uint64 `protobuf:"varint,2,opt,name=deweysPerKB,proto3" json:"deweysPerKB,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *PriceCheckResponse) Reset() { *m = PriceCheckResponse{} } +func (m *PriceCheckResponse) String() string { return proto.CompactTextString(m) } +func (*PriceCheckResponse) ProtoMessage() {} +func (*PriceCheckResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_183aee39e18f30c9, []int{2} +} + +func (m *PriceCheckResponse) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_PriceCheckResponse.Unmarshal(m, b) +} +func (m *PriceCheckResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_PriceCheckResponse.Marshal(b, m, deterministic) +} +func (m *PriceCheckResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_PriceCheckResponse.Merge(m, src) +} +func (m *PriceCheckResponse) XXX_Size() int { + return xxx_messageInfo_PriceCheckResponse.Size(m) +} +func (m *PriceCheckResponse) XXX_DiscardUnknown() { + xxx_messageInfo_PriceCheckResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_PriceCheckResponse proto.InternalMessageInfo + +func (m *PriceCheckResponse) GetError() *Error { + if m != nil { + return m.Error + } + return nil +} + +func (m *PriceCheckResponse) GetDeweysPerKB() uint64 { + if m != nil { + return m.DeweysPerKB + } + return 0 +} + +// are any of the hashs available for download, or are any of the hashes desired for upload +// NOTE: if any hashes are stream hashes, and the server has the manifest but not all the content +// blobs, the server may reply that it needs extra blobs that were not in the original request +type HashesRequest struct { + Hashes []string `protobuf:"bytes,1,rep,name=hashes,proto3" json:"hashes,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *HashesRequest) Reset() { *m = HashesRequest{} } +func (m *HashesRequest) String() string { return proto.CompactTextString(m) } +func (*HashesRequest) ProtoMessage() {} +func (*HashesRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_183aee39e18f30c9, []int{3} +} + +func (m *HashesRequest) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_HashesRequest.Unmarshal(m, b) +} +func (m *HashesRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_HashesRequest.Marshal(b, m, deterministic) +} +func (m *HashesRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_HashesRequest.Merge(m, src) +} +func (m *HashesRequest) XXX_Size() int { + return xxx_messageInfo_HashesRequest.Size(m) +} +func (m *HashesRequest) XXX_DiscardUnknown() { + xxx_messageInfo_HashesRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_HashesRequest proto.InternalMessageInfo + +func (m *HashesRequest) GetHashes() []string { + if m != nil { + return m.Hashes + } + return nil +} + +type HashesResponse struct { + Error *Error `protobuf:"bytes,1,opt,name=error,proto3" json:"error,omitempty"` + Hashes map[string]bool `protobuf:"bytes,2,rep,name=hashes,proto3" json:"hashes,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"varint,2,opt,name=value,proto3"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *HashesResponse) Reset() { *m = HashesResponse{} } +func (m *HashesResponse) String() string { return proto.CompactTextString(m) } +func (*HashesResponse) ProtoMessage() {} +func (*HashesResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_183aee39e18f30c9, []int{4} +} + +func (m *HashesResponse) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_HashesResponse.Unmarshal(m, b) +} +func (m *HashesResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_HashesResponse.Marshal(b, m, deterministic) +} +func (m *HashesResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_HashesResponse.Merge(m, src) +} +func (m *HashesResponse) XXX_Size() int { + return xxx_messageInfo_HashesResponse.Size(m) +} +func (m *HashesResponse) XXX_DiscardUnknown() { + xxx_messageInfo_HashesResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_HashesResponse proto.InternalMessageInfo + +func (m *HashesResponse) GetError() *Error { + if m != nil { + return m.Error + } + return nil +} + +func (m *HashesResponse) GetHashes() map[string]bool { + if m != nil { + return m.Hashes + } + return nil +} + +// download the hash +type DownloadRequest struct { + Hash string `protobuf:"bytes,1,opt,name=hash,proto3" json:"hash,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *DownloadRequest) Reset() { *m = DownloadRequest{} } +func (m *DownloadRequest) String() string { return proto.CompactTextString(m) } +func (*DownloadRequest) ProtoMessage() {} +func (*DownloadRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_183aee39e18f30c9, []int{5} +} + +func (m *DownloadRequest) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_DownloadRequest.Unmarshal(m, b) +} +func (m *DownloadRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_DownloadRequest.Marshal(b, m, deterministic) +} +func (m *DownloadRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_DownloadRequest.Merge(m, src) +} +func (m *DownloadRequest) XXX_Size() int { + return xxx_messageInfo_DownloadRequest.Size(m) +} +func (m *DownloadRequest) XXX_DiscardUnknown() { + xxx_messageInfo_DownloadRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_DownloadRequest proto.InternalMessageInfo + +func (m *DownloadRequest) GetHash() string { + if m != nil { + return m.Hash + } + return "" +} + +type DownloadResponse struct { + Error *Error `protobuf:"bytes,1,opt,name=error,proto3" json:"error,omitempty"` + Hash string `protobuf:"bytes,2,opt,name=hash,proto3" json:"hash,omitempty"` + Blob []byte `protobuf:"bytes,3,opt,name=blob,proto3" json:"blob,omitempty"` + Address string `protobuf:"bytes,4,opt,name=address,proto3" json:"address,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *DownloadResponse) Reset() { *m = DownloadResponse{} } +func (m *DownloadResponse) String() string { return proto.CompactTextString(m) } +func (*DownloadResponse) ProtoMessage() {} +func (*DownloadResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_183aee39e18f30c9, []int{6} +} + +func (m *DownloadResponse) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_DownloadResponse.Unmarshal(m, b) +} +func (m *DownloadResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_DownloadResponse.Marshal(b, m, deterministic) +} +func (m *DownloadResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_DownloadResponse.Merge(m, src) +} +func (m *DownloadResponse) XXX_Size() int { + return xxx_messageInfo_DownloadResponse.Size(m) +} +func (m *DownloadResponse) XXX_DiscardUnknown() { + xxx_messageInfo_DownloadResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_DownloadResponse proto.InternalMessageInfo + +func (m *DownloadResponse) GetError() *Error { + if m != nil { + return m.Error + } + return nil +} + +func (m *DownloadResponse) GetHash() string { + if m != nil { + return m.Hash + } + return "" +} + +func (m *DownloadResponse) GetBlob() []byte { + if m != nil { + return m.Blob + } + return nil +} + +func (m *DownloadResponse) GetAddress() string { + if m != nil { + return m.Address + } + return "" +} + +// upload the hash +type UploadRequest struct { + Hash string `protobuf:"bytes,1,opt,name=hash,proto3" json:"hash,omitempty"` + Blob []byte `protobuf:"bytes,2,opt,name=blob,proto3" json:"blob,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *UploadRequest) Reset() { *m = UploadRequest{} } +func (m *UploadRequest) String() string { return proto.CompactTextString(m) } +func (*UploadRequest) ProtoMessage() {} +func (*UploadRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_183aee39e18f30c9, []int{7} +} + +func (m *UploadRequest) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_UploadRequest.Unmarshal(m, b) +} +func (m *UploadRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_UploadRequest.Marshal(b, m, deterministic) +} +func (m *UploadRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_UploadRequest.Merge(m, src) +} +func (m *UploadRequest) XXX_Size() int { + return xxx_messageInfo_UploadRequest.Size(m) +} +func (m *UploadRequest) XXX_DiscardUnknown() { + xxx_messageInfo_UploadRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_UploadRequest proto.InternalMessageInfo + +func (m *UploadRequest) GetHash() string { + if m != nil { + return m.Hash + } + return "" +} + +func (m *UploadRequest) GetBlob() []byte { + if m != nil { + return m.Blob + } + return nil +} + +type UploadResponse struct { + Error *Error `protobuf:"bytes,1,opt,name=error,proto3" json:"error,omitempty"` + Hash string `protobuf:"bytes,2,opt,name=hash,proto3" json:"hash,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *UploadResponse) Reset() { *m = UploadResponse{} } +func (m *UploadResponse) String() string { return proto.CompactTextString(m) } +func (*UploadResponse) ProtoMessage() {} +func (*UploadResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_183aee39e18f30c9, []int{8} +} + +func (m *UploadResponse) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_UploadResponse.Unmarshal(m, b) +} +func (m *UploadResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_UploadResponse.Marshal(b, m, deterministic) +} +func (m *UploadResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_UploadResponse.Merge(m, src) +} +func (m *UploadResponse) XXX_Size() int { + return xxx_messageInfo_UploadResponse.Size(m) +} +func (m *UploadResponse) XXX_DiscardUnknown() { + xxx_messageInfo_UploadResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_UploadResponse proto.InternalMessageInfo + +func (m *UploadResponse) GetError() *Error { + if m != nil { + return m.Error + } + return nil +} + +func (m *UploadResponse) GetHash() string { + if m != nil { + return m.Hash + } + return "" +} + +func init() { + proto.RegisterType((*Error)(nil), "blobex.Error") + proto.RegisterType((*PriceCheckRequest)(nil), "blobex.PriceCheckRequest") + proto.RegisterType((*PriceCheckResponse)(nil), "blobex.PriceCheckResponse") + proto.RegisterType((*HashesRequest)(nil), "blobex.HashesRequest") + proto.RegisterType((*HashesResponse)(nil), "blobex.HashesResponse") + proto.RegisterMapType((map[string]bool)(nil), "blobex.HashesResponse.HashesEntry") + proto.RegisterType((*DownloadRequest)(nil), "blobex.DownloadRequest") + proto.RegisterType((*DownloadResponse)(nil), "blobex.DownloadResponse") + proto.RegisterType((*UploadRequest)(nil), "blobex.UploadRequest") + proto.RegisterType((*UploadResponse)(nil), "blobex.UploadResponse") +} + +// Reference imports to suppress errors if they are not otherwise used. +var _ context.Context +var _ grpc.ClientConn + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +const _ = grpc.SupportPackageIsVersion4 + +// BlobExchangeClient is the client API for BlobExchange service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. +type BlobExchangeClient interface { + PriceCheck(ctx context.Context, in *PriceCheckRequest, opts ...grpc.CallOption) (*PriceCheckResponse, error) + DownloadCheck(ctx context.Context, in *HashesRequest, opts ...grpc.CallOption) (*HashesResponse, error) + Download(ctx context.Context, opts ...grpc.CallOption) (BlobExchange_DownloadClient, error) + UploadOffer(ctx context.Context, in *HashesRequest, opts ...grpc.CallOption) (*HashesResponse, error) + Upload(ctx context.Context, opts ...grpc.CallOption) (BlobExchange_UploadClient, error) +} + +type blobExchangeClient struct { + cc *grpc.ClientConn +} + +func NewBlobExchangeClient(cc *grpc.ClientConn) BlobExchangeClient { + return &blobExchangeClient{cc} +} + +func (c *blobExchangeClient) PriceCheck(ctx context.Context, in *PriceCheckRequest, opts ...grpc.CallOption) (*PriceCheckResponse, error) { + out := new(PriceCheckResponse) + err := c.cc.Invoke(ctx, "/blobex.BlobExchange/PriceCheck", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *blobExchangeClient) DownloadCheck(ctx context.Context, in *HashesRequest, opts ...grpc.CallOption) (*HashesResponse, error) { + out := new(HashesResponse) + err := c.cc.Invoke(ctx, "/blobex.BlobExchange/DownloadCheck", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *blobExchangeClient) Download(ctx context.Context, opts ...grpc.CallOption) (BlobExchange_DownloadClient, error) { + stream, err := c.cc.NewStream(ctx, &_BlobExchange_serviceDesc.Streams[0], "/blobex.BlobExchange/Download", opts...) + if err != nil { + return nil, err + } + x := &blobExchangeDownloadClient{stream} + return x, nil +} + +type BlobExchange_DownloadClient interface { + Send(*DownloadRequest) error + Recv() (*DownloadResponse, error) + grpc.ClientStream +} + +type blobExchangeDownloadClient struct { + grpc.ClientStream +} + +func (x *blobExchangeDownloadClient) Send(m *DownloadRequest) error { + return x.ClientStream.SendMsg(m) +} + +func (x *blobExchangeDownloadClient) Recv() (*DownloadResponse, error) { + m := new(DownloadResponse) + if err := x.ClientStream.RecvMsg(m); err != nil { + return nil, err + } + return m, nil +} + +func (c *blobExchangeClient) UploadOffer(ctx context.Context, in *HashesRequest, opts ...grpc.CallOption) (*HashesResponse, error) { + out := new(HashesResponse) + err := c.cc.Invoke(ctx, "/blobex.BlobExchange/UploadOffer", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *blobExchangeClient) Upload(ctx context.Context, opts ...grpc.CallOption) (BlobExchange_UploadClient, error) { + stream, err := c.cc.NewStream(ctx, &_BlobExchange_serviceDesc.Streams[1], "/blobex.BlobExchange/Upload", opts...) + if err != nil { + return nil, err + } + x := &blobExchangeUploadClient{stream} + return x, nil +} + +type BlobExchange_UploadClient interface { + Send(*UploadRequest) error + Recv() (*UploadResponse, error) + grpc.ClientStream +} + +type blobExchangeUploadClient struct { + grpc.ClientStream +} + +func (x *blobExchangeUploadClient) Send(m *UploadRequest) error { + return x.ClientStream.SendMsg(m) +} + +func (x *blobExchangeUploadClient) Recv() (*UploadResponse, error) { + m := new(UploadResponse) + if err := x.ClientStream.RecvMsg(m); err != nil { + return nil, err + } + return m, nil +} + +// BlobExchangeServer is the server API for BlobExchange service. +type BlobExchangeServer interface { + PriceCheck(context.Context, *PriceCheckRequest) (*PriceCheckResponse, error) + DownloadCheck(context.Context, *HashesRequest) (*HashesResponse, error) + Download(BlobExchange_DownloadServer) error + UploadOffer(context.Context, *HashesRequest) (*HashesResponse, error) + Upload(BlobExchange_UploadServer) error +} + +func RegisterBlobExchangeServer(s *grpc.Server, srv BlobExchangeServer) { + s.RegisterService(&_BlobExchange_serviceDesc, srv) +} + +func _BlobExchange_PriceCheck_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(PriceCheckRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(BlobExchangeServer).PriceCheck(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/blobex.BlobExchange/PriceCheck", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(BlobExchangeServer).PriceCheck(ctx, req.(*PriceCheckRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _BlobExchange_DownloadCheck_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(HashesRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(BlobExchangeServer).DownloadCheck(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/blobex.BlobExchange/DownloadCheck", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(BlobExchangeServer).DownloadCheck(ctx, req.(*HashesRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _BlobExchange_Download_Handler(srv interface{}, stream grpc.ServerStream) error { + return srv.(BlobExchangeServer).Download(&blobExchangeDownloadServer{stream}) +} + +type BlobExchange_DownloadServer interface { + Send(*DownloadResponse) error + Recv() (*DownloadRequest, error) + grpc.ServerStream +} + +type blobExchangeDownloadServer struct { + grpc.ServerStream +} + +func (x *blobExchangeDownloadServer) Send(m *DownloadResponse) error { + return x.ServerStream.SendMsg(m) +} + +func (x *blobExchangeDownloadServer) Recv() (*DownloadRequest, error) { + m := new(DownloadRequest) + if err := x.ServerStream.RecvMsg(m); err != nil { + return nil, err + } + return m, nil +} + +func _BlobExchange_UploadOffer_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(HashesRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(BlobExchangeServer).UploadOffer(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/blobex.BlobExchange/UploadOffer", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(BlobExchangeServer).UploadOffer(ctx, req.(*HashesRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _BlobExchange_Upload_Handler(srv interface{}, stream grpc.ServerStream) error { + return srv.(BlobExchangeServer).Upload(&blobExchangeUploadServer{stream}) +} + +type BlobExchange_UploadServer interface { + Send(*UploadResponse) error + Recv() (*UploadRequest, error) + grpc.ServerStream +} + +type blobExchangeUploadServer struct { + grpc.ServerStream +} + +func (x *blobExchangeUploadServer) Send(m *UploadResponse) error { + return x.ServerStream.SendMsg(m) +} + +func (x *blobExchangeUploadServer) Recv() (*UploadRequest, error) { + m := new(UploadRequest) + if err := x.ServerStream.RecvMsg(m); err != nil { + return nil, err + } + return m, nil +} + +var _BlobExchange_serviceDesc = grpc.ServiceDesc{ + ServiceName: "blobex.BlobExchange", + HandlerType: (*BlobExchangeServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "PriceCheck", + Handler: _BlobExchange_PriceCheck_Handler, + }, + { + MethodName: "DownloadCheck", + Handler: _BlobExchange_DownloadCheck_Handler, + }, + { + MethodName: "UploadOffer", + Handler: _BlobExchange_UploadOffer_Handler, + }, + }, + Streams: []grpc.StreamDesc{ + { + StreamName: "Download", + Handler: _BlobExchange_Download_Handler, + ServerStreams: true, + ClientStreams: true, + }, + { + StreamName: "Upload", + Handler: _BlobExchange_Upload_Handler, + ServerStreams: true, + ClientStreams: true, + }, + }, + Metadata: "blobex.proto", +} + +func init() { proto.RegisterFile("blobex.proto", fileDescriptor_183aee39e18f30c9) } + +var fileDescriptor_183aee39e18f30c9 = []byte{ + // 441 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xa4, 0x94, 0xcd, 0x6e, 0xd4, 0x30, + 0x10, 0xc7, 0xeb, 0xec, 0x07, 0xdd, 0xc9, 0xa6, 0x94, 0x01, 0x4a, 0xd8, 0x53, 0x64, 0x84, 0xc8, + 0xa9, 0x42, 0x8b, 0x10, 0x50, 0x09, 0x84, 0x5a, 0x22, 0x81, 0x38, 0x50, 0x59, 0xe2, 0xc4, 0x29, + 0x1f, 0xd3, 0x06, 0x35, 0xc4, 0x8b, 0xbd, 0xa5, 0xcd, 0x3b, 0xf1, 0x46, 0xbc, 0x0c, 0x8a, 0x1d, + 0x37, 0xbb, 0x6d, 0x25, 0xb4, 0xe2, 0x36, 0x33, 0x9e, 0xf9, 0xfd, 0x27, 0xfe, 0x5b, 0x81, 0x69, + 0x56, 0xc9, 0x8c, 0x2e, 0xf7, 0x17, 0x4a, 0x2e, 0x25, 0x8e, 0x6d, 0xc6, 0x5f, 0xc2, 0x28, 0x51, + 0x4a, 0x2a, 0x44, 0x18, 0xe6, 0xb2, 0xa0, 0x90, 0x45, 0x2c, 0x0e, 0x84, 0x89, 0x31, 0x84, 0x3b, + 0x3f, 0x48, 0xeb, 0xf4, 0x94, 0x42, 0x2f, 0x62, 0xf1, 0x44, 0xb8, 0x94, 0xdf, 0x87, 0x7b, 0xc7, + 0xea, 0x7b, 0x4e, 0x47, 0x25, 0xe5, 0x67, 0x82, 0x7e, 0x9e, 0x93, 0x5e, 0xf2, 0x6f, 0x80, 0xab, + 0x45, 0xbd, 0x90, 0xb5, 0x26, 0x7c, 0x02, 0x23, 0x6a, 0x15, 0x0c, 0xd9, 0x9f, 0x07, 0xfb, 0xdd, + 0x1e, 0x46, 0x56, 0xd8, 0x33, 0x8c, 0xc0, 0x2f, 0xe8, 0x82, 0x1a, 0x7d, 0x4c, 0xea, 0xf3, 0xa1, + 0x51, 0x1b, 0x8a, 0xd5, 0x12, 0x7f, 0x06, 0xc1, 0xc7, 0x54, 0x97, 0xa4, 0x3b, 0x35, 0xdc, 0x83, + 0x71, 0x69, 0x0a, 0x21, 0x8b, 0x06, 0xf1, 0x44, 0x74, 0x19, 0xff, 0xcd, 0x60, 0xc7, 0x75, 0x6e, + 0xb2, 0xc2, 0xc1, 0x15, 0xcf, 0x8b, 0x06, 0xb1, 0x3f, 0xe7, 0xae, 0x6b, 0x1d, 0xd6, 0xa5, 0x49, + 0xbd, 0x54, 0x8d, 0xd3, 0x9c, 0xbd, 0x01, 0x7f, 0xa5, 0x8c, 0xbb, 0x30, 0x38, 0xa3, 0xc6, 0xa8, + 0x4d, 0x44, 0x1b, 0xe2, 0x03, 0x18, 0xfd, 0x4a, 0xab, 0x73, 0x7b, 0x8f, 0xdb, 0xc2, 0x26, 0x07, + 0xde, 0x6b, 0xc6, 0x9f, 0xc2, 0xdd, 0x0f, 0xf2, 0xa2, 0xae, 0x64, 0x5a, 0xb8, 0x2f, 0x43, 0x18, + 0xb6, 0xdc, 0x6e, 0xde, 0xc4, 0xbc, 0x81, 0xdd, 0xbe, 0x6d, 0x93, 0xcf, 0x72, 0x30, 0xaf, 0x87, + 0xb5, 0xb5, 0xb6, 0x35, 0x1c, 0x44, 0x2c, 0x9e, 0x0a, 0x13, 0xb7, 0x5e, 0xa7, 0x45, 0xa1, 0x48, + 0xeb, 0x70, 0x68, 0xbd, 0xee, 0x52, 0xfe, 0x0a, 0x82, 0xaf, 0x8b, 0x7f, 0xec, 0x77, 0x85, 0xf4, + 0x7a, 0x24, 0xff, 0x04, 0x3b, 0x6e, 0xf0, 0x3f, 0x37, 0x9e, 0xff, 0xf1, 0x60, 0x7a, 0x58, 0xc9, + 0x2c, 0xb9, 0xcc, 0xcb, 0xb4, 0x3e, 0x25, 0x4c, 0x00, 0xfa, 0xb7, 0x86, 0x8f, 0x1d, 0xe8, 0xc6, + 0xa3, 0x9c, 0xcd, 0x6e, 0x3b, 0xb2, 0xeb, 0xf0, 0x2d, 0x7c, 0x0f, 0x81, 0xbb, 0x56, 0x4b, 0x7a, + 0x78, 0xdd, 0x75, 0x4b, 0xd9, 0xbb, 0xfd, 0x31, 0xf0, 0x2d, 0x3c, 0x82, 0x6d, 0x47, 0xc0, 0x47, + 0xae, 0xeb, 0x9a, 0xa3, 0xb3, 0xf0, 0xe6, 0x81, 0x03, 0xc4, 0xec, 0x39, 0xc3, 0x77, 0xe0, 0xdb, + 0x9b, 0xfa, 0x72, 0x72, 0x42, 0x6a, 0xf3, 0x25, 0xde, 0xc2, 0xd8, 0xce, 0xf7, 0xa3, 0x6b, 0x96, + 0xf5, 0xa3, 0xeb, 0x86, 0x58, 0xf9, 0x6c, 0x6c, 0xfe, 0x09, 0x2f, 0xfe, 0x06, 0x00, 0x00, 0xff, + 0xff, 0x7a, 0xcb, 0xab, 0x18, 0x23, 0x04, 0x00, 0x00, +} diff --git a/blobex/blobex.proto b/blobex/blobex.proto new file mode 100644 index 0000000..5b5e28d --- /dev/null +++ b/blobex/blobex.proto @@ -0,0 +1,86 @@ +syntax = "proto3"; + +package blobex; + +/* + +## Errors +- invalid request +- banned for nonpayment +- banned for uploading unwanted blobs +- blob not wanted +- blob not available +- not accepting blobs + +## Considerations + +- there are two requests to upload a blob. how to reduce that to one? + - UploadCheck checks for many hashes at once. if you're just uploading one or a few, just do it and handle the error + +- how to avoid receiving the whole blob and then determining the blob is not wanted? may not ever be possible + +- is avail check necessary? just request what you want for download + - maybe you want to check multiple blobs at once? + +- how to check for wanted blobs from stream hash? + +- prices should be set by hosts, since they are offering blobs for download and have the best information on prices. but request is initiated by client. how do we make sure clients are not overpaying without making them make two requests for each blob? + +- should we have another request to submit proof of payment? or at least a txid? + +*/ + +service BlobExchange { + rpc PriceCheck(PriceCheckRequest) returns (PriceCheckResponse) {} + rpc DownloadCheck(HashesRequest) returns (HashesResponse) {} + rpc Download(stream DownloadRequest) returns (stream DownloadResponse) {} + rpc UploadOffer(HashesRequest) returns (HashesResponse) {} + rpc Upload(stream UploadRequest) returns (stream UploadResponse) {} +} + +message Error { + // should we enum the error codes? + uint32 code = 1; + string message = 2; +} + +// how much does the host charge per kb at the moment +message PriceCheckRequest { +} +message PriceCheckResponse{ + Error error = 1; + uint64 deweysPerKB = 2; +} + +// are any of the hashs available for download, or are any of the hashes desired for upload +// NOTE: if any hashes are stream hashes, and the server has the manifest but not all the content +// blobs, the server may reply that it needs extra blobs that were not in the original request +message HashesRequest { + repeated string hashes = 1; +} +message HashesResponse { + Error error = 1; + map hashes = 2; +} + +// download the hash +message DownloadRequest { + string hash = 1; +} +message DownloadResponse { + Error error = 1; + string hash = 2; + bytes blob = 3; + string address = 4; // address where payment for data download should be sent +} + +// upload the hash +message UploadRequest { + string hash = 1; + bytes blob = 2; +} +message UploadResponse { + Error error = 1; + string hash = 2; +} + diff --git a/blobex/proto.sh b/blobex/proto.sh new file mode 100755 index 0000000..2e53353 --- /dev/null +++ b/blobex/proto.sh @@ -0,0 +1,29 @@ +#!/bin/bash + +set -euo pipefail +#set -x + +version_gte() { + [ "$1" = "$(echo -e "$1\n$2" | sort -V | tail -n1)" ] +} + +DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" + + +hash protoc 2>/dev/null || { echo >&2 -e 'error: protoc binary not found\nDownload it from https://github.com/google/protobuf/releases and put it in your path.\nMake sure you get the one starting with `protoc`, not `protobuf`.'; exit 1; } + + +PROTOC="$(which protoc)" +VERSION="$($PROTOC --version | cut -d' ' -f2)" +MIN_VERSION="3.0" + +version_gte "$VERSION" "$MIN_VERSION" || { echo >&2 "error: protoc version must be >= $MIN_VERSION (your $PROTOC is $VERSION)"; exit 1; } + + +hash protoc-gen-go 2>/dev/null || go get -u github.com/golang/protobuf/protoc-gen-go +hash protoc-gen-go 2>/dev/null || { echo >&2 'error: Make sure $GOPATH/bin is in your $PATH'; exit 1; } + + +find . -type f -iname '*.pb.go' -delete + +protoc --proto_path=. blobex.proto --go_out=plugins=grpc:. \ No newline at end of file diff --git a/blobex/server.go b/blobex/server.go new file mode 100644 index 0000000..c37254b --- /dev/null +++ b/blobex/server.go @@ -0,0 +1,49 @@ +package blobex + +import ( + "fmt" + "net" + + "github.com/lbryio/lbry.go/errors" + + "golang.org/x/net/context" + "google.golang.org/grpc" +) + +type Server struct { + pricePerKB uint64 +} + +func ListenAndServe(port int) (*grpc.Server, error) { + listener, err := net.Listen("tcp", fmt.Sprintf(":%d", port)) + if err != nil { + return nil, errors.Prefix("failed to listen", err) + } + grpcServer := grpc.NewServer() + RegisterBlobExchangeServer(grpcServer, &Server{}) + // determine whether to use TLS + err = grpcServer.Serve(listener) + return grpcServer, err +} + +func (s *Server) PriceCheck(ctx context.Context, r *PriceCheckRequest) (*PriceCheckResponse, error) { + return &PriceCheckResponse{ + DeweysPerKB: s.pricePerKB, + }, nil +} + +func (s *Server) DownloadCheck(context.Context, *HashesRequest) (*HashesResponse, error) { + return nil, nil +} + +func (s *Server) Download(BlobExchange_DownloadServer) error { + return nil +} + +func (s *Server) UploadOffer(context.Context, *HashesRequest) (*HashesResponse, error) { + return nil, nil +} + +func (s *Server) Upload(BlobExchange_UploadServer) error { + return nil +}