storage node order sending (#1535)

This commit is contained in:
Egon Elbre 2019-03-21 15:24:26 +02:00 committed by GitHub
parent 60035caade
commit 2c5c2c29da
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 637 additions and 45 deletions

View File

@ -4,10 +4,12 @@
package pb
import (
context "context"
fmt "fmt"
_ "github.com/gogo/protobuf/gogoproto"
proto "github.com/gogo/protobuf/proto"
timestamp "github.com/golang/protobuf/ptypes/timestamp"
grpc "google.golang.org/grpc"
math "math"
)
@ -63,6 +65,34 @@ func (PieceAction) EnumDescriptor() ([]byte, []int) {
return fileDescriptor_e0f5d4cf0fc9e41b, []int{0}
}
type SettlementResponse_Status int32
const (
SettlementResponse_INVALID SettlementResponse_Status = 0
SettlementResponse_ACCEPTED SettlementResponse_Status = 1
SettlementResponse_REJECTED SettlementResponse_Status = 2
)
var SettlementResponse_Status_name = map[int32]string{
0: "INVALID",
1: "ACCEPTED",
2: "REJECTED",
}
var SettlementResponse_Status_value = map[string]int32{
"INVALID": 0,
"ACCEPTED": 1,
"REJECTED": 2,
}
func (x SettlementResponse_Status) String() string {
return proto.EnumName(SettlementResponse_Status_name, int32(x))
}
func (SettlementResponse_Status) EnumDescriptor() ([]byte, []int) {
return fileDescriptor_e0f5d4cf0fc9e41b, []int{4, 0}
}
// OrderLimit2 is provided by satellite to execute specific action on storage node within some limits
type OrderLimit2 struct {
// unique serial to avoid replay attacks
@ -246,47 +276,247 @@ func (m *PieceHash) GetSignature() []byte {
return nil
}
type SettlementRequest struct {
Limit *OrderLimit2 `protobuf:"bytes,1,opt,name=limit,proto3" json:"limit,omitempty"`
Order *Order2 `protobuf:"bytes,2,opt,name=order,proto3" json:"order,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *SettlementRequest) Reset() { *m = SettlementRequest{} }
func (m *SettlementRequest) String() string { return proto.CompactTextString(m) }
func (*SettlementRequest) ProtoMessage() {}
func (*SettlementRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_e0f5d4cf0fc9e41b, []int{3}
}
func (m *SettlementRequest) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_SettlementRequest.Unmarshal(m, b)
}
func (m *SettlementRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_SettlementRequest.Marshal(b, m, deterministic)
}
func (m *SettlementRequest) XXX_Merge(src proto.Message) {
xxx_messageInfo_SettlementRequest.Merge(m, src)
}
func (m *SettlementRequest) XXX_Size() int {
return xxx_messageInfo_SettlementRequest.Size(m)
}
func (m *SettlementRequest) XXX_DiscardUnknown() {
xxx_messageInfo_SettlementRequest.DiscardUnknown(m)
}
var xxx_messageInfo_SettlementRequest proto.InternalMessageInfo
func (m *SettlementRequest) GetLimit() *OrderLimit2 {
if m != nil {
return m.Limit
}
return nil
}
func (m *SettlementRequest) GetOrder() *Order2 {
if m != nil {
return m.Order
}
return nil
}
type SettlementResponse struct {
SerialNumber SerialNumber `protobuf:"bytes,1,opt,name=serial_number,json=serialNumber,proto3,customtype=SerialNumber" json:"serial_number"`
Status SettlementResponse_Status `protobuf:"varint,2,opt,name=status,proto3,enum=orders.SettlementResponse_Status" json:"status,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *SettlementResponse) Reset() { *m = SettlementResponse{} }
func (m *SettlementResponse) String() string { return proto.CompactTextString(m) }
func (*SettlementResponse) ProtoMessage() {}
func (*SettlementResponse) Descriptor() ([]byte, []int) {
return fileDescriptor_e0f5d4cf0fc9e41b, []int{4}
}
func (m *SettlementResponse) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_SettlementResponse.Unmarshal(m, b)
}
func (m *SettlementResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_SettlementResponse.Marshal(b, m, deterministic)
}
func (m *SettlementResponse) XXX_Merge(src proto.Message) {
xxx_messageInfo_SettlementResponse.Merge(m, src)
}
func (m *SettlementResponse) XXX_Size() int {
return xxx_messageInfo_SettlementResponse.Size(m)
}
func (m *SettlementResponse) XXX_DiscardUnknown() {
xxx_messageInfo_SettlementResponse.DiscardUnknown(m)
}
var xxx_messageInfo_SettlementResponse proto.InternalMessageInfo
func (m *SettlementResponse) GetStatus() SettlementResponse_Status {
if m != nil {
return m.Status
}
return SettlementResponse_INVALID
}
func init() {
proto.RegisterEnum("orders.PieceAction", PieceAction_name, PieceAction_value)
proto.RegisterEnum("orders.SettlementResponse_Status", SettlementResponse_Status_name, SettlementResponse_Status_value)
proto.RegisterType((*OrderLimit2)(nil), "orders.OrderLimit2")
proto.RegisterType((*Order2)(nil), "orders.Order2")
proto.RegisterType((*PieceHash)(nil), "orders.PieceHash")
proto.RegisterType((*SettlementRequest)(nil), "orders.SettlementRequest")
proto.RegisterType((*SettlementResponse)(nil), "orders.SettlementResponse")
}
func init() { proto.RegisterFile("orders.proto", fileDescriptor_e0f5d4cf0fc9e41b) }
var fileDescriptor_e0f5d4cf0fc9e41b = []byte{
// 502 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xa4, 0x52, 0x4d, 0x6b, 0xdb, 0x40,
0x10, 0x8d, 0xfc, 0x21, 0xdb, 0xe3, 0x2f, 0xb1, 0x09, 0x45, 0x98, 0x82, 0x4d, 0x4e, 0x6e, 0x02,
0x32, 0x75, 0xa1, 0xd0, 0xa3, 0x83, 0x44, 0x2a, 0x30, 0xae, 0xd9, 0xc8, 0x3d, 0xf4, 0x62, 0xd6,
0xd1, 0x56, 0x5e, 0x2a, 0x69, 0x85, 0xb4, 0x82, 0xfe, 0x82, 0x1e, 0xfb, 0xbb, 0xfa, 0x1b, 0x7a,
0xc8, 0x6f, 0x29, 0x1a, 0xc9, 0x1f, 0x2d, 0x81, 0x1c, 0x7a, 0xdb, 0x37, 0xef, 0xbd, 0x99, 0x65,
0xde, 0x40, 0x4f, 0xa6, 0x3e, 0x4f, 0x33, 0x2b, 0x49, 0xa5, 0x92, 0x44, 0x2f, 0xd1, 0x08, 0x02,
0x19, 0xc8, 0xb2, 0x36, 0x1a, 0x07, 0x52, 0x06, 0x21, 0x9f, 0x21, 0xda, 0xe5, 0x5f, 0x67, 0x4a,
0x44, 0x3c, 0x53, 0x2c, 0x4a, 0x4a, 0xc1, 0xf5, 0xcf, 0x06, 0x74, 0x3f, 0x15, 0xbe, 0xa5, 0x88,
0x84, 0x9a, 0x93, 0x0f, 0xd0, 0xcf, 0x78, 0x2a, 0x58, 0xb8, 0x8d, 0xf3, 0x68, 0xc7, 0x53, 0x53,
0x9b, 0x68, 0xd3, 0xde, 0xdd, 0xd5, 0xaf, 0xa7, 0xf1, 0xc5, 0xef, 0xa7, 0x71, 0xef, 0x01, 0xc9,
0x15, 0x72, 0xb4, 0x97, 0x9d, 0x21, 0xf2, 0x16, 0x7a, 0x19, 0x53, 0x3c, 0x0c, 0x85, 0xe2, 0x5b,
0xe1, 0x9b, 0x35, 0x74, 0x0e, 0x2a, 0xa7, 0xbe, 0x92, 0x3e, 0x77, 0x6d, 0xda, 0x3d, 0x6a, 0x5c,
0x9f, 0xdc, 0x42, 0x27, 0x4f, 0x42, 0x11, 0x7f, 0x2b, 0xf4, 0xf5, 0x67, 0xf5, 0xed, 0x52, 0xe0,
0xfa, 0xe4, 0x3d, 0x0c, 0x33, 0x25, 0x53, 0x16, 0xf0, 0x6d, 0x2c, 0x7d, 0x1c, 0xd1, 0x78, 0xd6,
0xd2, 0xaf, 0x64, 0x08, 0x7d, 0x72, 0x03, 0xed, 0x44, 0xf0, 0x47, 0x34, 0x34, 0xd1, 0x30, 0xac,
0x0c, 0xad, 0x75, 0x51, 0x77, 0x6d, 0xda, 0x42, 0x81, 0xeb, 0x93, 0x2b, 0x68, 0x86, 0xc5, 0x22,
0x4c, 0x7d, 0xa2, 0x4d, 0xeb, 0xb4, 0x04, 0xe4, 0x16, 0x74, 0xf6, 0xa8, 0x84, 0x8c, 0xcd, 0xd6,
0x44, 0x9b, 0x0e, 0xe6, 0x97, 0x56, 0xb5, 0x78, 0xf4, 0x2f, 0x90, 0xa2, 0x95, 0x84, 0x38, 0x60,
0x94, 0xe3, 0xf8, 0xf7, 0x44, 0xa4, 0x0c, 0x6d, 0xed, 0x89, 0x36, 0xed, 0xce, 0x47, 0x56, 0x99,
0x86, 0x75, 0x48, 0xc3, 0xf2, 0x0e, 0x69, 0xd0, 0x21, 0x7a, 0x9c, 0xa3, 0xa5, 0x68, 0x83, 0x43,
0xce, 0xdb, 0x74, 0x5e, 0x6e, 0x83, 0x9e, 0xb3, 0x36, 0x33, 0xb8, 0x3c, 0x85, 0x92, 0x89, 0x20,
0x66, 0x2a, 0x4f, 0xb9, 0x09, 0xc5, 0x1e, 0x28, 0x39, 0x52, 0x0f, 0x07, 0xe6, 0xfa, 0x87, 0x06,
0x3a, 0x1e, 0xc4, 0x7f, 0xdd, 0xc2, 0x2b, 0xd0, 0x59, 0x24, 0xf3, 0x58, 0xe1, 0x15, 0xd4, 0x69,
0x85, 0xc8, 0x1b, 0x30, 0xaa, 0xc0, 0x4f, 0x7f, 0xc1, 0xdc, 0xe9, 0xb0, 0xac, 0x9f, 0x3e, 0x22,
0xa0, 0x83, 0xeb, 0xfd, 0xc8, 0xb2, 0xfd, 0x5f, 0x19, 0x6a, 0x2f, 0x64, 0x48, 0xa0, 0xb1, 0x67,
0xd9, 0xbe, 0xbc, 0x3f, 0x8a, 0x6f, 0xf2, 0x1a, 0x3a, 0xff, 0x0e, 0x3c, 0x15, 0x6e, 0x02, 0xe8,
0x9e, 0x25, 0x49, 0xba, 0xd0, 0x72, 0x57, 0x9f, 0x17, 0x4b, 0xd7, 0x36, 0x2e, 0x48, 0x0b, 0xea,
0xeb, 0x8d, 0x67, 0x68, 0xc5, 0xe3, 0xde, 0xf1, 0x8c, 0x1a, 0xe9, 0x43, 0xe7, 0xde, 0xf1, 0xb6,
0x8b, 0x8d, 0xed, 0x7a, 0x46, 0x9d, 0x0c, 0x00, 0x0a, 0x48, 0x9d, 0xf5, 0xc2, 0xa5, 0x46, 0xa3,
0xc0, 0xeb, 0xcd, 0x11, 0x37, 0x09, 0x80, 0x6e, 0x3b, 0x4b, 0xc7, 0x73, 0x0c, 0xfd, 0xae, 0xf1,
0xa5, 0x96, 0xec, 0x76, 0x3a, 0x06, 0xf7, 0xee, 0x4f, 0x00, 0x00, 0x00, 0xff, 0xff, 0x69, 0x39,
0x9a, 0x2f, 0xbf, 0x03, 0x00, 0x00,
// 634 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xa4, 0x53, 0x4d, 0x6f, 0xd3, 0x40,
0x10, 0xed, 0xe6, 0xc3, 0x49, 0x26, 0x69, 0x62, 0xb6, 0x15, 0x0a, 0x11, 0x52, 0x43, 0xc4, 0x21,
0xb4, 0x52, 0x4a, 0x8d, 0x84, 0xd4, 0x63, 0xda, 0x58, 0xc5, 0xa8, 0x2a, 0xd1, 0xc6, 0xe5, 0xc0,
0x25, 0x72, 0xea, 0xc5, 0xb5, 0x70, 0xbc, 0xc6, 0xbb, 0x96, 0xf8, 0x05, 0x1c, 0xf9, 0x47, 0xdc,
0xf9, 0x0d, 0x1c, 0xfa, 0x5b, 0x90, 0xc7, 0x4e, 0xe2, 0x42, 0x50, 0x0f, 0xbd, 0xf9, 0xcd, 0xbc,
0xb7, 0x6f, 0x77, 0xde, 0x18, 0x5a, 0x22, 0x76, 0x79, 0x2c, 0x47, 0x51, 0x2c, 0x94, 0xa0, 0x5a,
0x86, 0x7a, 0xe0, 0x09, 0x4f, 0x64, 0xb5, 0xde, 0x81, 0x27, 0x84, 0x17, 0xf0, 0x63, 0x44, 0x8b,
0xe4, 0xf3, 0xb1, 0xf2, 0x97, 0x5c, 0x2a, 0x67, 0x19, 0x65, 0x84, 0xc1, 0x8f, 0x0a, 0x34, 0x3f,
0xa4, 0xba, 0x4b, 0x7f, 0xe9, 0x2b, 0x83, 0x9e, 0xc2, 0xae, 0xe4, 0xb1, 0xef, 0x04, 0xf3, 0x30,
0x59, 0x2e, 0x78, 0xdc, 0x25, 0x7d, 0x32, 0x6c, 0x9d, 0xed, 0xff, 0xba, 0x3b, 0xd8, 0xf9, 0x7d,
0x77, 0xd0, 0x9a, 0x61, 0xf3, 0x0a, 0x7b, 0xac, 0x25, 0x0b, 0x88, 0x9e, 0x40, 0x4b, 0x3a, 0x8a,
0x07, 0x81, 0xaf, 0xf8, 0xdc, 0x77, 0xbb, 0x25, 0x54, 0xb6, 0x73, 0xa5, 0x76, 0x25, 0x5c, 0x6e,
0x4d, 0x58, 0x73, 0xcd, 0xb1, 0x5c, 0x7a, 0x04, 0x8d, 0x24, 0x0a, 0xfc, 0xf0, 0x4b, 0xca, 0x2f,
0x6f, 0xe5, 0xd7, 0x33, 0x82, 0xe5, 0xd2, 0xb7, 0xd0, 0x91, 0x4a, 0xc4, 0x8e, 0xc7, 0xe7, 0xa1,
0x70, 0xd1, 0xa2, 0xb2, 0x55, 0xb2, 0x9b, 0xd3, 0x10, 0xba, 0xf4, 0x10, 0xea, 0x91, 0xcf, 0x6f,
0x50, 0x50, 0x45, 0x41, 0x27, 0x17, 0xd4, 0xa6, 0x69, 0xdd, 0x9a, 0xb0, 0x1a, 0x12, 0x2c, 0x97,
0xee, 0x43, 0x35, 0x48, 0x07, 0xd1, 0xd5, 0xfa, 0x64, 0x58, 0x66, 0x19, 0xa0, 0x47, 0xa0, 0x39,
0x37, 0xca, 0x17, 0x61, 0xb7, 0xd6, 0x27, 0xc3, 0xb6, 0xb1, 0x37, 0xca, 0x07, 0x8f, 0xfa, 0x31,
0xb6, 0x58, 0x4e, 0xa1, 0x26, 0xe8, 0x99, 0x1d, 0xff, 0x16, 0xf9, 0xb1, 0x83, 0xb2, 0x7a, 0x9f,
0x0c, 0x9b, 0x46, 0x6f, 0x94, 0xa5, 0x31, 0x5a, 0xa5, 0x31, 0xb2, 0x57, 0x69, 0xb0, 0x0e, 0x6a,
0xcc, 0xb5, 0x24, 0x3d, 0x06, 0x4d, 0x8a, 0xc7, 0x34, 0x1e, 0x3e, 0x06, 0x35, 0x85, 0x63, 0x8e,
0x61, 0x6f, 0x13, 0x8a, 0xf4, 0xbd, 0xd0, 0x51, 0x49, 0xcc, 0xbb, 0x90, 0xce, 0x81, 0xd1, 0x75,
0x6b, 0xb6, 0xea, 0x0c, 0xbe, 0x13, 0xd0, 0x70, 0x21, 0x1e, 0xb5, 0x0b, 0x4f, 0x41, 0x73, 0x96,
0x22, 0x09, 0x15, 0x6e, 0x41, 0x99, 0xe5, 0x88, 0xbe, 0x02, 0x3d, 0x0f, 0x7c, 0x73, 0x17, 0xcc,
0x9d, 0x75, 0xb2, 0xfa, 0xe6, 0x22, 0x3e, 0x34, 0x70, 0xbc, 0xef, 0x1c, 0x79, 0x7b, 0x2f, 0x43,
0xf2, 0x40, 0x86, 0x14, 0x2a, 0xb7, 0x8e, 0xbc, 0xcd, 0xf6, 0x8f, 0xe1, 0x37, 0x7d, 0x0e, 0x8d,
0xbf, 0x0d, 0x37, 0x85, 0x81, 0x0b, 0x4f, 0x66, 0x5c, 0xa9, 0x80, 0x2f, 0x79, 0xa8, 0x18, 0xff,
0x9a, 0x70, 0x99, 0x5e, 0x35, 0x5f, 0x05, 0x82, 0x53, 0x5f, 0x67, 0x5e, 0xf8, 0x5b, 0x56, 0xfb,
0xf1, 0x12, 0xaa, 0xd8, 0x44, 0xcb, 0xa6, 0xd1, 0xbe, 0x47, 0x35, 0x58, 0xd6, 0x1c, 0xfc, 0x24,
0x40, 0x8b, 0x36, 0x32, 0x12, 0xa1, 0xe4, 0x8f, 0x99, 0xf2, 0x29, 0x68, 0x52, 0x39, 0x2a, 0x91,
0x68, 0xdc, 0x36, 0x5e, 0xac, 0x8c, 0xff, 0xb5, 0x19, 0xcd, 0x90, 0xc8, 0x72, 0xc1, 0xe0, 0x04,
0xb4, 0xac, 0x42, 0x9b, 0x50, 0xb3, 0xae, 0x3e, 0x8e, 0x2f, 0xad, 0x89, 0xbe, 0x43, 0x5b, 0x50,
0x1f, 0x9f, 0x9f, 0x9b, 0x53, 0xdb, 0x9c, 0xe8, 0x24, 0x45, 0xcc, 0x7c, 0x6f, 0x9e, 0xa7, 0xa8,
0x74, 0xe8, 0x41, 0xb3, 0xb0, 0xef, 0xf7, 0x75, 0x35, 0x28, 0x4f, 0xaf, 0x6d, 0x9d, 0xa4, 0x1f,
0x17, 0xa6, 0xad, 0x97, 0xe8, 0x2e, 0x34, 0x2e, 0x4c, 0x7b, 0x3e, 0xbe, 0x9e, 0x58, 0xb6, 0x5e,
0xa6, 0x6d, 0x80, 0x14, 0x32, 0x73, 0x3a, 0xb6, 0x98, 0x5e, 0x49, 0xf1, 0xf4, 0x7a, 0x8d, 0xab,
0x14, 0x40, 0x9b, 0x98, 0x97, 0xa6, 0x6d, 0xea, 0x9a, 0x31, 0xcb, 0x37, 0x50, 0x52, 0x0b, 0x60,
0xf3, 0x14, 0xfa, 0x6c, 0xdb, 0xf3, 0x30, 0xac, 0x5e, 0xef, 0xff, 0x2f, 0x1f, 0xec, 0x0c, 0xc9,
0x6b, 0x72, 0x56, 0xf9, 0x54, 0x8a, 0x16, 0x0b, 0x0d, 0xff, 0x99, 0x37, 0x7f, 0x02, 0x00, 0x00,
0xff, 0xff, 0xbc, 0xfe, 0x4a, 0x7c, 0x3a, 0x05, 0x00, 0x00,
}
// 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
// OrdersClient is the client API for Orders service.
//
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream.
type OrdersClient interface {
Settlement(ctx context.Context, opts ...grpc.CallOption) (Orders_SettlementClient, error)
}
type ordersClient struct {
cc *grpc.ClientConn
}
func NewOrdersClient(cc *grpc.ClientConn) OrdersClient {
return &ordersClient{cc}
}
func (c *ordersClient) Settlement(ctx context.Context, opts ...grpc.CallOption) (Orders_SettlementClient, error) {
stream, err := c.cc.NewStream(ctx, &_Orders_serviceDesc.Streams[0], "/orders.Orders/Settlement", opts...)
if err != nil {
return nil, err
}
x := &ordersSettlementClient{stream}
return x, nil
}
type Orders_SettlementClient interface {
Send(*SettlementRequest) error
Recv() (*SettlementResponse, error)
grpc.ClientStream
}
type ordersSettlementClient struct {
grpc.ClientStream
}
func (x *ordersSettlementClient) Send(m *SettlementRequest) error {
return x.ClientStream.SendMsg(m)
}
func (x *ordersSettlementClient) Recv() (*SettlementResponse, error) {
m := new(SettlementResponse)
if err := x.ClientStream.RecvMsg(m); err != nil {
return nil, err
}
return m, nil
}
// OrdersServer is the server API for Orders service.
type OrdersServer interface {
Settlement(Orders_SettlementServer) error
}
func RegisterOrdersServer(s *grpc.Server, srv OrdersServer) {
s.RegisterService(&_Orders_serviceDesc, srv)
}
func _Orders_Settlement_Handler(srv interface{}, stream grpc.ServerStream) error {
return srv.(OrdersServer).Settlement(&ordersSettlementServer{stream})
}
type Orders_SettlementServer interface {
Send(*SettlementResponse) error
Recv() (*SettlementRequest, error)
grpc.ServerStream
}
type ordersSettlementServer struct {
grpc.ServerStream
}
func (x *ordersSettlementServer) Send(m *SettlementResponse) error {
return x.ServerStream.SendMsg(m)
}
func (x *ordersSettlementServer) Recv() (*SettlementRequest, error) {
m := new(SettlementRequest)
if err := x.ServerStream.RecvMsg(m); err != nil {
return nil, err
}
return m, nil
}
var _Orders_serviceDesc = grpc.ServiceDesc{
ServiceName: "orders.Orders",
HandlerType: (*OrdersServer)(nil),
Methods: []grpc.MethodDesc{},
Streams: []grpc.StreamDesc{
{
StreamName: "Settlement",
Handler: _Orders_Settlement_Handler,
ServerStreams: true,
ClientStreams: true,
},
},
Metadata: "orders.proto",
}

View File

@ -60,4 +60,25 @@ message PieceHash {
bytes hash = 2;
// signature either satellite or storage node
bytes signature = 3;
}
service Orders {
rpc Settlement(stream SettlementRequest) returns (stream SettlementResponse) {}
}
message SettlementRequest {
OrderLimit2 limit = 1;
Order2 order = 2;
}
message SettlementResponse {
enum Status {
INVALID = 0;
ACCEPTED = 1;
REJECTED = 2;
}
bytes serial_number = 1 [(gogoproto.customtype) = "SerialNumber", (gogoproto.nullable) = false];
Status status = 2;
}

View File

@ -38,8 +38,13 @@ func TestOrders(t *testing.T) {
serialNumber := newRandomSerial()
// basic test
_, err := ordersdb.ListUnsent(ctx, 100)
emptyUnsent, err := ordersdb.ListUnsent(ctx, 100)
require.NoError(t, err)
require.Len(t, emptyUnsent, 0)
emptyArchive, err := ordersdb.ListArchived(ctx, 100)
require.NoError(t, err)
require.Len(t, emptyArchive, 0)
now := ptypes.TimestampNow()
@ -78,8 +83,48 @@ func TestOrders(t *testing.T) {
unsent, err := ordersdb.ListUnsent(ctx, 100)
require.NoError(t, err)
require.Empty(t, cmp.Diff([]*orders.Info{info}, unsent, cmp.Comparer(pb.Equal)))
// list by group
unsentGrouped, err := ordersdb.ListUnsentBySatellite(ctx)
require.NoError(t, err)
expectedGrouped := map[storj.NodeID][]*orders.Info{
satellite0.ID: []*orders.Info{
{Limit: limit, Order: order},
},
}
require.Empty(t, cmp.Diff(expectedGrouped, unsentGrouped, cmp.Comparer(pb.Equal)))
// test archival
err = ordersdb.Archive(ctx, satellite0.ID, serialNumber, orders.StatusAccepted)
require.NoError(t, err)
// duplicate archive
err = ordersdb.Archive(ctx, satellite0.ID, serialNumber, orders.StatusRejected)
require.Error(t, err)
// shouldn't be in unsent list
unsent, err = ordersdb.ListUnsent(ctx, 100)
require.NoError(t, err)
require.Len(t, unsent, 0)
// it should now be in the archive
archived, err := ordersdb.ListArchived(ctx, 100)
require.NoError(t, err)
require.Len(t, archived, 1)
require.Empty(t, cmp.Diff([]*orders.ArchivedInfo{
{
Limit: limit,
Order: order,
Uplink: uplink.PeerIdentity(),
Status: orders.StatusAccepted,
ArchivedAt: archived[0].ArchivedAt,
},
}, archived, cmp.Comparer(pb.Equal)))
})
}

View File

@ -5,13 +5,17 @@ package orders
import (
"context"
"io"
"time"
"go.uber.org/zap"
"golang.org/x/sync/errgroup"
"storj.io/storj/internal/sync2"
"storj.io/storj/pkg/identity"
"storj.io/storj/pkg/kademlia"
"storj.io/storj/pkg/pb"
"storj.io/storj/pkg/storj"
"storj.io/storj/pkg/transport"
)
@ -22,17 +26,46 @@ type Info struct {
Uplink *identity.PeerIdentity
}
// ArchivedInfo contains full information about an archived order.
type ArchivedInfo struct {
Limit *pb.OrderLimit2
Order *pb.Order2
Uplink *identity.PeerIdentity
Status Status
ArchivedAt time.Time
}
// Status is the archival status of the order.
type Status byte
// Statuses for satellite responses.
const (
StatusUnsent Status = iota
StatusAccepted
StatusRejected
)
// DB implements storing orders for sending to the satellite.
type DB interface {
// Enqueue inserts order to the list of orders needing to be sent to the satellite.
Enqueue(ctx context.Context, info *Info) error
// ListUnsent returns orders that haven't been sent yet.
ListUnsent(ctx context.Context, limit int) ([]*Info, error)
// ListUnsentBySatellite returns orders that haven't been sent yet grouped by satellite.
ListUnsentBySatellite(ctx context.Context) (map[storj.NodeID][]*Info, error)
// Archive marks order as being handled.
Archive(ctx context.Context, satellite storj.NodeID, serial storj.SerialNumber, status Status) error
// ListArchived returns orders that have been sent.
ListArchived(ctx context.Context, limit int) ([]*ArchivedInfo, error)
}
// SenderConfig defines configuration for sending orders.
type SenderConfig struct {
Interval time.Duration
Interval time.Duration `help:"duration between sending" default:"1h0m0s"`
Timeout time.Duration `help:"timeout for sending" default:"1h0m0s"`
}
// Sender sends every interval unsent orders to the satellite.
@ -40,18 +73,134 @@ type Sender struct {
log *zap.Logger
config SenderConfig
client transport.Client
kademlia *kademlia.Kademlia
orders DB
transport transport.Client
kademlia *kademlia.Kademlia
orders DB
Loop sync2.Cycle
}
// NewSender creates an order sender.
func NewSender(log *zap.Logger, client transport.Client, kademlia *kademlia.Kademlia, orders DB, config SenderConfig) *Sender {
func NewSender(log *zap.Logger, transport transport.Client, kademlia *kademlia.Kademlia, orders DB, config SenderConfig) *Sender {
return &Sender{
log: log,
config: config,
client: client,
kademlia: kademlia,
orders: orders,
log: log,
transport: transport,
kademlia: kademlia,
orders: orders,
Loop: *sync2.NewCycle(config.Interval),
}
}
// Run sends orders on every interval to the appropriate satellites.
func (sender *Sender) Run(ctx context.Context) error {
return sender.Loop.Run(ctx, func(ctx context.Context) error {
sender.log.Debug("sending")
ordersBySatellite, err := sender.orders.ListUnsentBySatellite(ctx)
if err != nil {
sender.log.Error("listing orders", zap.Error(err))
return nil
}
if len(ordersBySatellite) > 0 {
var group errgroup.Group
ctx, cancel := context.WithTimeout(ctx, sender.config.Timeout)
defer cancel()
for satelliteID, orders := range ordersBySatellite {
satelliteID, orders := satelliteID, orders
group.Go(func() error {
sender.Settle(ctx, satelliteID, orders)
return nil
})
}
} else {
sender.log.Debug("no orders to send")
}
return nil
})
}
// Settle uploads agreements to the satellite.
func (sender *Sender) Settle(ctx context.Context, satelliteID storj.NodeID, orders []*Info) {
log := sender.log.Named(satelliteID.String())
log.Info("sending", zap.Int("count", len(orders)))
defer log.Info("finished")
satellite, err := sender.kademlia.FindNode(ctx, satelliteID)
if err != nil {
log.Error("unable to find satellite on the network", zap.Error(err))
return
}
conn, err := sender.transport.DialNode(ctx, &satellite)
if err != nil {
log.Error("unable to connect to the satellite", zap.Error(err))
return
}
defer func() {
if err := conn.Close(); err != nil {
log.Warn("failed to close connection", zap.Error(err))
}
}()
client, err := pb.NewOrdersClient(conn).Settlement(ctx)
if err != nil {
log.Error("failed to start settlement", zap.Error(err))
return
}
var group errgroup.Group
group.Go(func() error {
for _, order := range orders {
err := client.Send(&pb.SettlementRequest{
Limit: order.Limit,
Order: order.Order,
})
if err != nil {
return err
}
}
return client.CloseSend()
})
for {
response, err := client.Recv()
if err != nil {
if err == io.EOF {
break
}
log.Error("failed to receive response", zap.Error(err))
break
}
switch response.Status {
case pb.SettlementResponse_ACCEPTED:
err = sender.orders.Archive(ctx, satelliteID, response.SerialNumber, StatusAccepted)
if err != nil {
log.Error("failed to archive order as accepted", zap.Stringer("serial", response.SerialNumber), zap.Error(err))
}
case pb.SettlementResponse_REJECTED:
err = sender.orders.Archive(ctx, satelliteID, response.SerialNumber, StatusRejected)
if err != nil {
log.Error("failed to archive order as rejected", zap.Stringer("serial", response.SerialNumber), zap.Error(err))
}
default:
log.Error("unexpected response", zap.Error(err))
}
}
if err := group.Wait(); err != nil {
log.Error("sending agreements returned an error", zap.Error(err))
}
}
// Close stops the sending service.
func (sender *Sender) Close() error {
sender.Loop.Stop()
return nil
}

View File

@ -6,12 +6,14 @@ package storagenodedb
import (
"context"
"database/sql"
"time"
"github.com/gogo/protobuf/proto"
"github.com/golang/protobuf/ptypes"
"github.com/zeebo/errs"
"storj.io/storj/pkg/pb"
"storj.io/storj/pkg/storj"
"storj.io/storj/storagenode/orders"
)
@ -113,3 +115,148 @@ func (db *ordersdb) ListUnsent(ctx context.Context, limit int) (_ []*orders.Info
return infos, ErrInfo.Wrap(rows.Err())
}
// ListUnsentBySatellite returns orders that haven't been sent yet grouped by satellite.
// Does not return uplink identity.
func (db *ordersdb) ListUnsentBySatellite(ctx context.Context) (map[storj.NodeID][]*orders.Info, error) {
defer db.locked()()
// TODO: add some limiting
rows, err := db.db.Query(`
SELECT order_limit_serialized, order_serialized
FROM unsent_order
`)
if err != nil {
if err == sql.ErrNoRows {
return nil, nil
}
return nil, ErrInfo.Wrap(err)
}
defer func() { err = errs.Combine(err, rows.Close()) }()
infos := map[storj.NodeID][]*orders.Info{}
for rows.Next() {
var limitSerialized []byte
var orderSerialized []byte
err := rows.Scan(&limitSerialized, &orderSerialized)
if err != nil {
return nil, ErrInfo.Wrap(err)
}
var info orders.Info
info.Limit = &pb.OrderLimit2{}
info.Order = &pb.Order2{}
err = proto.Unmarshal(limitSerialized, info.Limit)
if err != nil {
return nil, ErrInfo.Wrap(err)
}
err = proto.Unmarshal(orderSerialized, info.Order)
if err != nil {
return nil, ErrInfo.Wrap(err)
}
infos[info.Limit.SatelliteId] = append(infos[info.Limit.SatelliteId], &info)
}
return infos, ErrInfo.Wrap(rows.Err())
}
// Archive marks order as being handled.
func (db *ordersdb) Archive(ctx context.Context, satellite storj.NodeID, serial storj.SerialNumber, status orders.Status) error {
defer db.locked()()
result, err := db.db.Exec(`
INSERT INTO order_archive (
satellite_id, serial_number,
order_limit_serialized, order_serialized,
uplink_cert_id,
status, archived_at
) SELECT
satellite_id, serial_number,
order_limit_serialized, order_serialized,
uplink_cert_id,
?, ?
FROM unsent_order
WHERE satellite_id = ? AND serial_number = ?;
DELETE FROM unsent_order
WHERE satellite_id = ? AND serial_number = ?;
`, int(status), time.Now(), satellite, serial, satellite, serial)
if err != nil {
return ErrInfo.Wrap(err)
}
count, err := result.RowsAffected()
if err != nil {
return ErrInfo.Wrap(err)
}
if count == 0 {
return ErrInfo.New("order was not in unsent list")
}
return nil
}
// ListArchived returns orders that have been sent.
func (db *ordersdb) ListArchived(ctx context.Context, limit int) ([]*orders.ArchivedInfo, error) {
defer db.locked()()
rows, err := db.db.Query(`
SELECT order_limit_serialized, order_serialized, certificate.peer_identity,
status, archived_at
FROM order_archive
INNER JOIN certificate on order_archive.uplink_cert_id = certificate.cert_id
LIMIT ?
`, limit)
if err != nil {
if err == sql.ErrNoRows {
return nil, nil
}
return nil, ErrInfo.Wrap(err)
}
defer func() { err = errs.Combine(err, rows.Close()) }()
var infos []*orders.ArchivedInfo
for rows.Next() {
var limitSerialized []byte
var orderSerialized []byte
var uplinkIdentity []byte
var status int
var archivedAt time.Time
err := rows.Scan(&limitSerialized, &orderSerialized, &uplinkIdentity, &status, &archivedAt)
if err != nil {
return nil, ErrInfo.Wrap(err)
}
var info orders.ArchivedInfo
info.Limit = &pb.OrderLimit2{}
info.Order = &pb.Order2{}
info.Status = orders.Status(status)
info.ArchivedAt = archivedAt
err = proto.Unmarshal(limitSerialized, info.Limit)
if err != nil {
return nil, ErrInfo.Wrap(err)
}
err = proto.Unmarshal(orderSerialized, info.Order)
if err != nil {
return nil, ErrInfo.Wrap(err)
}
info.Uplink, err = decodePeerIdentity(uplinkIdentity)
if err != nil {
return nil, ErrInfo.Wrap(err)
}
infos = append(infos, &info)
}
return infos, ErrInfo.Wrap(rows.Err())
}