satellite/metainfo: Verify storagenode signature on satellite upload (#2985)

This commit is contained in:
Maximillian von Briesen 2019-09-18 09:50:33 -04:00 committed by GitHub
parent fd20fa38c6
commit 574c96c350
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 499 additions and 320 deletions

View File

@ -2884,6 +2884,7 @@ func (m *SatSegmentID) GetSatelliteSignature() []byte {
} }
type SegmentCommitResponse struct { type SegmentCommitResponse struct {
SuccessfulPieces int32 `protobuf:"varint,1,opt,name=successful_pieces,json=successfulPieces,proto3" json:"successful_pieces,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"` XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"` XXX_sizecache int32 `json:"-"`
@ -2913,6 +2914,13 @@ func (m *SegmentCommitResponse) XXX_DiscardUnknown() {
var xxx_messageInfo_SegmentCommitResponse proto.InternalMessageInfo var xxx_messageInfo_SegmentCommitResponse proto.InternalMessageInfo
func (m *SegmentCommitResponse) GetSuccessfulPieces() int32 {
if m != nil {
return m.SuccessfulPieces
}
return 0
}
type SegmentMakeInlineRequest struct { type SegmentMakeInlineRequest struct {
StreamId StreamID `protobuf:"bytes,1,opt,name=stream_id,json=streamId,proto3,customtype=StreamID" json:"stream_id"` StreamId StreamID `protobuf:"bytes,1,opt,name=stream_id,json=streamId,proto3,customtype=StreamID" json:"stream_id"`
Position *SegmentPosition `protobuf:"bytes,2,opt,name=position,proto3" json:"position,omitempty"` Position *SegmentPosition `protobuf:"bytes,2,opt,name=position,proto3" json:"position,omitempty"`
@ -4883,233 +4891,234 @@ func init() {
func init() { proto.RegisterFile("metainfo.proto", fileDescriptor_631e2f30a93cd64e) } func init() { proto.RegisterFile("metainfo.proto", fileDescriptor_631e2f30a93cd64e) }
var fileDescriptor_631e2f30a93cd64e = []byte{ var fileDescriptor_631e2f30a93cd64e = []byte{
// 3607 bytes of a gzipped FileDescriptorProto // 3629 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xd4, 0x5b, 0xcd, 0x6f, 0x1c, 0xc7, 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xd4, 0x5b, 0xcd, 0x6f, 0x1b, 0xd7,
0x95, 0xe7, 0x7c, 0xcf, 0xbc, 0x19, 0x72, 0x86, 0x45, 0x8a, 0x1a, 0x0d, 0x45, 0x51, 0x6a, 0x7d, 0xb5, 0x17, 0xbf, 0xc9, 0x43, 0x4a, 0x24, 0xaf, 0x64, 0x99, 0xa6, 0x2c, 0xcb, 0x1e, 0x7f, 0xc4,
0x58, 0x06, 0x6c, 0xca, 0xa0, 0x77, 0x17, 0x5e, 0x58, 0x5e, 0x2f, 0xa9, 0xa1, 0xc4, 0xb1, 0x45, 0xc1, 0x4b, 0xe4, 0x40, 0x79, 0xef, 0x21, 0x0f, 0x71, 0x5e, 0x9e, 0x64, 0xca, 0x16, 0x13, 0x4b,
0x8a, 0x6e, 0x4a, 0x96, 0x56, 0x6b, 0x67, 0xd0, 0x64, 0x17, 0xc9, 0x8e, 0x66, 0xa6, 0x27, 0xdd, 0x56, 0x46, 0x76, 0xec, 0xe7, 0x97, 0xbc, 0xc1, 0x88, 0x73, 0x25, 0x4d, 0x4d, 0x72, 0xd8, 0x99,
0x3d, 0x0e, 0xe5, 0x53, 0x0e, 0x01, 0x82, 0xc0, 0x39, 0xe4, 0x98, 0x93, 0x2f, 0x41, 0x4e, 0xf9, 0x61, 0x2a, 0x67, 0xd5, 0x45, 0x81, 0xa2, 0x48, 0x17, 0x5d, 0x76, 0x95, 0x4d, 0xd1, 0x55, 0xff,
0x0b, 0x02, 0x04, 0xb9, 0x26, 0x08, 0x82, 0x1c, 0x9c, 0x5b, 0x02, 0x38, 0x39, 0xe5, 0x98, 0x8b, 0x82, 0x02, 0x45, 0xb7, 0x2d, 0x8a, 0xa2, 0x8b, 0x74, 0xd7, 0x02, 0x69, 0x57, 0x5d, 0x76, 0x93,
0x6f, 0x01, 0x02, 0x04, 0xf5, 0xd5, 0x5d, 0xdd, 0x5d, 0xdd, 0x33, 0xa4, 0x28, 0x01, 0xbe, 0x75, 0x5d, 0x81, 0x02, 0xc5, 0xfd, 0x9a, 0xb9, 0xf3, 0x49, 0x4a, 0x96, 0x0d, 0x64, 0xc7, 0x39, 0xf7,
0xbf, 0x7a, 0xf5, 0xaa, 0xea, 0x7d, 0xfc, 0xea, 0xd5, 0xab, 0x6e, 0x98, 0xe9, 0x63, 0xcf, 0xb0, 0xdc, 0x33, 0xf7, 0x9e, 0x8f, 0xdf, 0x39, 0xf7, 0x5c, 0x0e, 0xcc, 0x0d, 0xb0, 0xab, 0x9b, 0xc3,
0x06, 0x07, 0xf6, 0xca, 0xd0, 0xb1, 0x3d, 0x1b, 0x95, 0xc5, 0x7b, 0xab, 0x81, 0x07, 0xfb, 0xce, 0x03, 0x6b, 0x75, 0x64, 0x5b, 0xae, 0x85, 0xca, 0xe2, 0xb9, 0xdd, 0xc0, 0xc3, 0x9e, 0xfd, 0x7c,
0xf3, 0xa1, 0x67, 0xd9, 0x03, 0xd6, 0xd6, 0x82, 0x43, 0xfb, 0x90, 0xf3, 0xb5, 0x96, 0x0f, 0x6d, 0xe4, 0x9a, 0xd6, 0x90, 0x8d, 0xb5, 0xe1, 0xd0, 0x3a, 0xe4, 0x7c, 0xed, 0x95, 0x43, 0xcb, 0x3a,
0xfb, 0xb0, 0x87, 0x6f, 0xd1, 0xb7, 0xbd, 0xd1, 0xc1, 0x2d, 0xcf, 0xea, 0x63, 0xd7, 0x33, 0xfa, 0xec, 0xe3, 0x5b, 0xf4, 0x69, 0x7f, 0x7c, 0x70, 0xcb, 0x35, 0x07, 0xd8, 0x71, 0xf5, 0xc1, 0x48,
0x43, 0xc1, 0x3c, 0xb0, 0x4d, 0xcc, 0x9f, 0xeb, 0x43, 0xdb, 0x1a, 0x78, 0xd8, 0x31, 0xf7, 0x38, 0x30, 0x0f, 0x2d, 0x03, 0xf3, 0xdf, 0xf5, 0x91, 0x65, 0x0e, 0x5d, 0x6c, 0x1b, 0xfb, 0x9c, 0x50,
0xa1, 0x66, 0x3b, 0x26, 0x76, 0x5c, 0xf6, 0xa6, 0xfd, 0x32, 0x07, 0xc5, 0xf5, 0xd1, 0xfe, 0x33, 0xb3, 0x6c, 0x03, 0xdb, 0x0e, 0x7b, 0x52, 0x7e, 0x91, 0x83, 0xe2, 0xc6, 0xb8, 0xf7, 0x0c, 0xbb,
0xec, 0x21, 0x04, 0xf9, 0x81, 0xd1, 0xc7, 0xcd, 0xcc, 0xe5, 0xcc, 0xcd, 0x9a, 0x4e, 0x9f, 0xd1, 0x08, 0x41, 0x7e, 0xa8, 0x0f, 0x70, 0x2b, 0x73, 0x39, 0x73, 0xb3, 0xa6, 0xd2, 0xdf, 0xe8, 0x1d,
0x3b, 0x50, 0x1d, 0x1a, 0xde, 0x51, 0x77, 0xdf, 0x1a, 0x1e, 0x61, 0xa7, 0x99, 0xbd, 0x9c, 0xb9, 0xa8, 0x8e, 0x74, 0xf7, 0x48, 0xeb, 0x99, 0xa3, 0x23, 0x6c, 0xb7, 0xb2, 0x97, 0x33, 0x37, 0xe7,
0x39, 0xb3, 0x7a, 0x7e, 0x45, 0x9a, 0xde, 0x1d, 0xda, 0xb2, 0x3b, 0xb2, 0x3c, 0xac, 0x03, 0xe1, 0xd6, 0xce, 0xaf, 0x4a, 0xcb, 0xbb, 0x43, 0x47, 0xf6, 0xc6, 0xa6, 0x8b, 0x55, 0x20, 0xbc, 0x8c,
0x65, 0x04, 0x74, 0x07, 0x60, 0xdf, 0xc1, 0x86, 0x87, 0xcd, 0xae, 0xe1, 0x35, 0x73, 0x97, 0x33, 0x80, 0xee, 0x00, 0xf4, 0x6c, 0xac, 0xbb, 0xd8, 0xd0, 0x74, 0xb7, 0x95, 0xbb, 0x9c, 0xb9, 0x59,
0x37, 0xab, 0xab, 0xad, 0x15, 0x36, 0xf3, 0x15, 0x31, 0xf3, 0x95, 0x87, 0x62, 0xe6, 0xeb, 0xe5, 0x5d, 0x6b, 0xaf, 0xb2, 0x95, 0xaf, 0x8a, 0x95, 0xaf, 0x3e, 0x14, 0x2b, 0xdf, 0x28, 0xff, 0xf6,
0xdf, 0x7d, 0xbd, 0x3c, 0xf5, 0xd3, 0xbf, 0x2e, 0x67, 0xf4, 0x0a, 0xef, 0xb7, 0xe6, 0xa1, 0xb7, 0xeb, 0x95, 0x99, 0x9f, 0xfc, 0x65, 0x25, 0xa3, 0x56, 0xf8, 0xbc, 0x75, 0x17, 0xbd, 0x05, 0x0b,
0x60, 0xde, 0xc4, 0x07, 0xc6, 0xa8, 0xe7, 0x75, 0x5d, 0x7c, 0xd8, 0xc7, 0x03, 0xaf, 0xeb, 0x5a, 0x06, 0x3e, 0xd0, 0xc7, 0x7d, 0x57, 0x73, 0xf0, 0xe1, 0x00, 0x0f, 0x5d, 0xcd, 0x31, 0x3f, 0xc7,
0x9f, 0xe3, 0x66, 0xfe, 0x72, 0xe6, 0x66, 0x4e, 0x47, 0xbc, 0x6d, 0x97, 0x35, 0xed, 0x5a, 0x9f, 0xad, 0xfc, 0xe5, 0xcc, 0xcd, 0x9c, 0x8a, 0xf8, 0xd8, 0x1e, 0x1b, 0xda, 0x33, 0x3f, 0xc7, 0xe8,
0x63, 0xf4, 0x18, 0x2e, 0x88, 0x1e, 0x0e, 0x36, 0x47, 0x03, 0xd3, 0x18, 0xec, 0x3f, 0xef, 0xba, 0x31, 0x5c, 0x10, 0x33, 0x6c, 0x6c, 0x8c, 0x87, 0x86, 0x3e, 0xec, 0x3d, 0xd7, 0x9c, 0xde, 0x11,
0xfb, 0x47, 0xb8, 0x8f, 0x9b, 0x05, 0x3a, 0x8b, 0xc5, 0x95, 0x40, 0x25, 0xba, 0xcf, 0xb3, 0x4b, 0x1e, 0xe0, 0x56, 0x81, 0xae, 0x62, 0x69, 0xd5, 0x57, 0x89, 0xea, 0xf1, 0xec, 0x51, 0x16, 0xf5,
0x59, 0xf4, 0xf3, 0xbc, 0x77, 0xb4, 0x01, 0x99, 0xb0, 0x24, 0x04, 0x07, 0xab, 0xef, 0x0e, 0x0d, 0x3c, 0x9f, 0x1d, 0x1e, 0x40, 0x06, 0x2c, 0x0b, 0xc1, 0xfe, 0xee, 0xb5, 0x91, 0x6e, 0xeb, 0x03,
0xc7, 0xe8, 0x63, 0x0f, 0x3b, 0x6e, 0xb3, 0x48, 0x85, 0x5f, 0x96, 0x75, 0xb3, 0xe1, 0x3f, 0xee, 0xec, 0x62, 0xdb, 0x69, 0x15, 0xa9, 0xf0, 0xcb, 0xb2, 0x6e, 0x36, 0xbd, 0x9f, 0xbb, 0x1e, 0x9f,
0xf8, 0x7c, 0xfa, 0x22, 0x17, 0xa3, 0x6a, 0x44, 0x4b, 0x00, 0x43, 0xc3, 0xf1, 0x06, 0xd8, 0xe9, 0xba, 0xc4, 0xc5, 0xc4, 0x0d, 0xa2, 0x65, 0x80, 0x91, 0x6e, 0xbb, 0x43, 0x6c, 0x6b, 0xa6, 0xd1,
0x5a, 0x66, 0xb3, 0x44, 0x2d, 0x51, 0xe1, 0x94, 0x8e, 0xa9, 0x59, 0x30, 0xc3, 0x8c, 0x75, 0xdf, 0x2a, 0x51, 0x4b, 0x54, 0x38, 0xa5, 0x6b, 0x28, 0x26, 0xcc, 0x31, 0x63, 0xdd, 0x37, 0x1d, 0xb7,
0x72, 0xbd, 0x8e, 0x87, 0xfb, 0x4a, 0xa3, 0x85, 0x55, 0x9f, 0x3d, 0x95, 0xea, 0xb5, 0x6f, 0xb2, 0xeb, 0xe2, 0x41, 0xac, 0xd1, 0x82, 0xaa, 0xcf, 0x9e, 0x4a, 0xf5, 0xca, 0x37, 0x59, 0x98, 0x67,
0x30, 0xc7, 0xc6, 0xba, 0x43, 0x69, 0x3a, 0xfe, 0xde, 0x08, 0xbb, 0x67, 0xed, 0x25, 0x49, 0x06, 0xef, 0xba, 0x43, 0x69, 0x2a, 0xfe, 0xee, 0x18, 0x3b, 0x67, 0xed, 0x25, 0x49, 0x06, 0xce, 0x9d,
0xce, 0x9d, 0xce, 0xc0, 0xf9, 0x97, 0x69, 0xe0, 0xc2, 0xd9, 0x1b, 0xb8, 0x18, 0x35, 0xf0, 0xff, 0xce, 0xc0, 0xf9, 0x97, 0x69, 0xe0, 0xc2, 0xd9, 0x1b, 0xb8, 0x18, 0x36, 0xf0, 0xff, 0xc0, 0x42,
0xc2, 0x7c, 0x58, 0xe9, 0xee, 0xd0, 0x1e, 0xb8, 0x18, 0xdd, 0x84, 0xe2, 0x1e, 0xa5, 0x53, 0xbd, 0x50, 0xe9, 0xce, 0xc8, 0x1a, 0x3a, 0x18, 0xdd, 0x84, 0xe2, 0x3e, 0xa5, 0x53, 0xbd, 0x57, 0xd7,
0x57, 0x57, 0x1b, 0x2b, 0x3e, 0x76, 0x30, 0x7e, 0x9d, 0xb7, 0x6b, 0x37, 0xa0, 0xc1, 0x28, 0xf7, 0x1a, 0xab, 0x1e, 0x76, 0x30, 0x7e, 0x95, 0x8f, 0x2b, 0x37, 0xa0, 0xc1, 0x28, 0xf7, 0xb0, 0x9b,
0xb0, 0x97, 0x62, 0x33, 0xed, 0x3d, 0x98, 0x95, 0xf8, 0x4e, 0x3c, 0xcc, 0xeb, 0xc2, 0x3b, 0xda, 0x62, 0x33, 0xe5, 0x3d, 0x68, 0x4a, 0x7c, 0x27, 0x7e, 0xcd, 0xeb, 0xc2, 0x3b, 0x3a, 0xb8, 0x8f,
0xb8, 0x87, 0x53, 0xbd, 0x43, 0x5b, 0x10, 0x6b, 0x12, 0xac, 0x6c, 0x30, 0xad, 0x2b, 0x66, 0x40, 0x53, 0xbd, 0x43, 0x59, 0x14, 0x7b, 0x12, 0xac, 0xec, 0x65, 0x8a, 0x26, 0x56, 0x40, 0x9c, 0x59,
0x9c, 0x59, 0x08, 0x58, 0x80, 0xe2, 0xfe, 0xc8, 0x71, 0x6d, 0x87, 0x8b, 0xe0, 0x6f, 0x68, 0x1e, 0x08, 0x58, 0x84, 0x62, 0x6f, 0x6c, 0x3b, 0x96, 0xcd, 0x45, 0xf0, 0x27, 0xb4, 0x00, 0x85, 0xbe,
0x0a, 0x3d, 0xab, 0x6f, 0x31, 0x77, 0x2e, 0xe8, 0xec, 0x05, 0x5d, 0x84, 0x8a, 0x69, 0x39, 0x78, 0x39, 0x30, 0x99, 0x3b, 0x17, 0x54, 0xf6, 0x80, 0x2e, 0x42, 0xc5, 0x30, 0x6d, 0xdc, 0x23, 0x4a,
0x9f, 0x28, 0x99, 0xfa, 0x4c, 0x41, 0x0f, 0x08, 0xda, 0x13, 0x40, 0xf2, 0x00, 0x7c, 0x8d, 0x2b, 0xa6, 0x3e, 0x53, 0x50, 0x7d, 0x82, 0xf2, 0x04, 0x90, 0xfc, 0x02, 0xbe, 0xc7, 0x55, 0x28, 0x98,
0x50, 0xb0, 0x3c, 0xdc, 0x77, 0x9b, 0x99, 0xcb, 0xb9, 0x9b, 0xd5, 0xd5, 0x66, 0x74, 0x89, 0x22, 0x2e, 0x1e, 0x38, 0xad, 0xcc, 0xe5, 0xdc, 0xcd, 0xea, 0x5a, 0x2b, 0xbc, 0x45, 0x11, 0x5a, 0x2a,
0xb4, 0x74, 0xc6, 0x46, 0x96, 0xd4, 0xb7, 0x1d, 0x4c, 0x07, 0x2e, 0xeb, 0xf4, 0x59, 0xdb, 0x81, 0x63, 0x23, 0x5b, 0x1a, 0x58, 0x36, 0xa6, 0x2f, 0x2e, 0xab, 0xf4, 0xb7, 0xb2, 0x0b, 0x4b, 0x8c,
0x45, 0xc6, 0xbc, 0x8b, 0xbd, 0x35, 0xcf, 0x73, 0xac, 0xbd, 0x11, 0x19, 0x31, 0x2d, 0x46, 0xc2, 0x79, 0x0f, 0xbb, 0xeb, 0xae, 0x6b, 0x9b, 0xfb, 0x63, 0xf2, 0xc6, 0xb4, 0x18, 0x09, 0x1a, 0x3e,
0x86, 0xcf, 0x46, 0x0d, 0x7f, 0x09, 0x2e, 0xaa, 0x25, 0x72, 0x65, 0xfd, 0x30, 0x03, 0x73, 0x6b, 0x1b, 0x36, 0xfc, 0x25, 0xb8, 0x18, 0x2f, 0x91, 0x2b, 0xeb, 0x07, 0x19, 0x98, 0x5f, 0x37, 0x0c,
0xa6, 0xe9, 0x60, 0xd7, 0xc5, 0xe6, 0x03, 0x82, 0xe0, 0xf7, 0xa9, 0x06, 0x6e, 0x0a, 0xbd, 0x30, 0x1b, 0x3b, 0x0e, 0x36, 0x1e, 0x10, 0x04, 0xbf, 0x4f, 0x35, 0x70, 0x53, 0xe8, 0x85, 0x19, 0x0c,
0x83, 0xa1, 0x15, 0x8e, 0xee, 0x01, 0x8b, 0xd0, 0xd5, 0x1d, 0x98, 0x77, 0x3d, 0xdb, 0x31, 0x0e, 0xad, 0x72, 0x74, 0xf7, 0x59, 0x84, 0xae, 0xee, 0xc0, 0x82, 0xe3, 0x5a, 0xb6, 0x7e, 0x88, 0x35,
0x71, 0x97, 0x6c, 0x0f, 0x5d, 0x83, 0x49, 0xe3, 0xf8, 0x30, 0xbb, 0x42, 0xf7, 0x8c, 0x6d, 0xdb, 0x92, 0x1e, 0x34, 0x9d, 0x49, 0xe3, 0xf8, 0xd0, 0x5c, 0xa5, 0x39, 0x63, 0xc7, 0x32, 0x30, 0x7f,
0xc4, 0x7c, 0x18, 0x1d, 0x71, 0x76, 0x89, 0xa6, 0x7d, 0x99, 0x85, 0x05, 0x1e, 0x8d, 0x8f, 0x1d, 0x8d, 0x8a, 0x38, 0xbb, 0x44, 0x53, 0xbe, 0xcc, 0xc2, 0x22, 0x8f, 0xc6, 0xc7, 0xb6, 0xe9, 0xd9,
0xcb, 0xb7, 0xfb, 0x83, 0x9e, 0x49, 0x2c, 0x27, 0xf9, 0x4e, 0x4d, 0x78, 0x0a, 0x51, 0x06, 0x09, 0xfd, 0x41, 0xdf, 0x20, 0x96, 0x93, 0x7c, 0xa7, 0x26, 0x3c, 0x85, 0x28, 0x83, 0x04, 0x3c, 0xdf,
0x78, 0xbe, 0x64, 0xfa, 0x8c, 0x9a, 0x50, 0xe2, 0xe1, 0xce, 0x23, 0x5d, 0xbc, 0xa2, 0x77, 0x01, 0x32, 0xfd, 0x8d, 0x5a, 0x50, 0xe2, 0xe1, 0xce, 0x23, 0x5d, 0x3c, 0xa2, 0x77, 0x01, 0xfc, 0xb0,
0x82, 0xb0, 0x9e, 0x24, 0x9e, 0x25, 0x76, 0xf4, 0x2e, 0xb4, 0xfa, 0xc6, 0xb1, 0x08, 0x5f, 0x6c, 0x9e, 0x26, 0x9e, 0x25, 0x76, 0xf4, 0x2e, 0xb4, 0x07, 0xfa, 0xb1, 0x08, 0x5f, 0x6c, 0x04, 0x31,
0x86, 0x31, 0xa5, 0x40, 0x47, 0x3a, 0xdf, 0x37, 0x8e, 0x37, 0x04, 0x83, 0x0c, 0x2c, 0x6d, 0x00, 0xa5, 0x40, 0xdf, 0x74, 0x7e, 0xa0, 0x1f, 0x6f, 0x0a, 0x06, 0x19, 0x58, 0x3a, 0x00, 0xf8, 0x78,
0x7c, 0x3c, 0xb4, 0x1c, 0x83, 0x3a, 0x53, 0xf1, 0x04, 0xa8, 0x29, 0xf5, 0xd3, 0xbe, 0xca, 0xc0, 0x64, 0xda, 0x3a, 0x75, 0xa6, 0xe2, 0x09, 0x50, 0x53, 0x9a, 0xa7, 0x7c, 0x95, 0x81, 0xf3, 0x41,
0xf9, 0xb0, 0x82, 0x98, 0x01, 0x89, 0x86, 0x36, 0xa1, 0x61, 0x08, 0x13, 0x76, 0xa9, 0x51, 0x84, 0x05, 0x31, 0x03, 0x12, 0x0d, 0x6d, 0x41, 0x43, 0x17, 0x26, 0xd4, 0xa8, 0x51, 0x84, 0x13, 0x2e,
0x13, 0x2e, 0x05, 0x4e, 0xa8, 0x30, 0xb2, 0x5e, 0xf7, 0xbb, 0xd1, 0x77, 0x17, 0xbd, 0x0d, 0xd3, 0xfb, 0x4e, 0x18, 0x63, 0x64, 0xb5, 0xee, 0x4d, 0xa3, 0xcf, 0x0e, 0x7a, 0x1b, 0x66, 0x6d, 0xcb,
0x8e, 0x6d, 0x7b, 0xdd, 0xa1, 0x85, 0xf7, 0xb1, 0xef, 0x4f, 0xeb, 0x75, 0x32, 0xa5, 0x3f, 0x7f, 0x72, 0xb5, 0x91, 0x89, 0x7b, 0xd8, 0xf3, 0xa7, 0x8d, 0x3a, 0x59, 0xd2, 0x9f, 0xbe, 0x5e, 0x29,
0xbd, 0x5c, 0xda, 0x21, 0xf4, 0x4e, 0x5b, 0xaf, 0x12, 0x2e, 0xf6, 0x62, 0x52, 0x94, 0x76, 0xac, 0xed, 0x12, 0x7a, 0xb7, 0xa3, 0x56, 0x09, 0x17, 0x7b, 0x30, 0x28, 0x4a, 0xdb, 0xe6, 0x67, 0xba,
0xcf, 0x0c, 0x0f, 0x77, 0x9f, 0xe1, 0xe7, 0x54, 0xf1, 0xb5, 0xf5, 0xf3, 0xbc, 0x4b, 0x9d, 0x72, 0x8b, 0xb5, 0x67, 0xf8, 0x39, 0x55, 0x7c, 0x6d, 0xe3, 0x3c, 0x9f, 0x52, 0xa7, 0x5c, 0xbb, 0x6c,
0xed, 0xb0, 0xf6, 0x0f, 0xf1, 0x73, 0x1d, 0x86, 0xfe, 0xb3, 0xf6, 0xfb, 0x60, 0x51, 0x77, 0xec, 0xfc, 0x43, 0xfc, 0x5c, 0x85, 0x91, 0xf7, 0x5b, 0xf9, 0x9d, 0xbf, 0xa9, 0x3b, 0xd6, 0x80, 0xac,
0x3e, 0x99, 0xd1, 0x59, 0x9b, 0xfd, 0x0d, 0x28, 0x71, 0x1b, 0x73, 0x9b, 0x23, 0xc9, 0xe6, 0x3b, 0xe8, 0xac, 0xcd, 0xfe, 0x06, 0x94, 0xb8, 0x8d, 0xb9, 0xcd, 0x91, 0x64, 0xf3, 0x5d, 0xf6, 0x4b,
0xec, 0x49, 0x17, 0x2c, 0xe8, 0x5d, 0xa8, 0xdb, 0x8e, 0x75, 0x68, 0x0d, 0x8c, 0x9e, 0xd0, 0x63, 0x15, 0x2c, 0xe8, 0x5d, 0xa8, 0x5b, 0xb6, 0x79, 0x68, 0x0e, 0xf5, 0xbe, 0xd0, 0x63, 0x81, 0xea,
0x81, 0xea, 0x51, 0xe5, 0xfe, 0x33, 0x82, 0x95, 0xe9, 0x4e, 0xdb, 0x84, 0x66, 0x64, 0x2d, 0x81, 0x31, 0xce, 0xfd, 0xe7, 0x04, 0x2b, 0xd3, 0x9d, 0xb2, 0x05, 0xad, 0xd0, 0x5e, 0x7c, 0x0b, 0x49,
0x85, 0xa4, 0x69, 0x64, 0xc6, 0x4e, 0x43, 0x33, 0xe0, 0x02, 0x97, 0xd4, 0xb6, 0xbf, 0x3f, 0xe8, 0xcb, 0xc8, 0x4c, 0x5c, 0x86, 0xa2, 0xc3, 0x05, 0x2e, 0xa9, 0x63, 0x7d, 0x6f, 0xd8, 0xb7, 0x74,
0xd9, 0x86, 0x79, 0xd6, 0x7a, 0xd1, 0xfe, 0x98, 0x81, 0x56, 0x6c, 0x8c, 0x97, 0xe1, 0x51, 0xd2, 0xe3, 0xac, 0xf5, 0xa2, 0xfc, 0x21, 0x03, 0xed, 0xc8, 0x3b, 0x5e, 0x86, 0x47, 0x49, 0x3b, 0xcf,
0xca, 0xb3, 0xe3, 0x0d, 0x70, 0x7a, 0x57, 0xfa, 0x14, 0xce, 0xf1, 0xf5, 0x74, 0x06, 0x07, 0xf6, 0x4e, 0x36, 0xc0, 0xe9, 0x5d, 0xe9, 0x53, 0x38, 0xc7, 0xf7, 0xd3, 0x1d, 0x1e, 0x58, 0x67, 0xae,
0x99, 0xeb, 0xeb, 0xae, 0x0f, 0x4f, 0x4c, 0xbc, 0xd2, 0xb4, 0xe3, 0x17, 0xa8, 0x75, 0x7d, 0x87, 0xaf, 0xbb, 0x1e, 0x3c, 0x31, 0xf1, 0xb1, 0xa6, 0x9d, 0xbc, 0x41, 0x45, 0xf3, 0x1c, 0x3e, 0x90,
0x0f, 0xed, 0x6f, 0x67, 0x37, 0xd1, 0x2f, 0x33, 0xbe, 0x1b, 0x86, 0xb7, 0xc5, 0xb3, 0x35, 0x6b, 0xdf, 0xce, 0x6e, 0xa1, 0x5f, 0x66, 0x3c, 0x37, 0x0c, 0xa6, 0xc5, 0xb3, 0x35, 0x6b, 0xc8, 0x50,
0xc4, 0x50, 0xd9, 0xc9, 0x0d, 0xf5, 0x97, 0x0c, 0x2c, 0x90, 0xad, 0x90, 0x4f, 0xd2, 0x9d, 0x40, 0xd9, 0xe9, 0x0d, 0xf5, 0xe7, 0x0c, 0x2c, 0x92, 0x54, 0xc8, 0x17, 0xe9, 0x4c, 0xa1, 0x81, 0x45,
0x03, 0x0b, 0x50, 0x1c, 0x3a, 0xf8, 0xc0, 0x3a, 0xe6, 0x3a, 0xe0, 0x6f, 0x68, 0x19, 0xaa, 0xae, 0x28, 0x8e, 0x6c, 0x7c, 0x60, 0x1e, 0x73, 0x1d, 0xf0, 0x27, 0xb4, 0x02, 0x55, 0xc7, 0xd5, 0x6d,
0x67, 0x38, 0x5e, 0xd7, 0x38, 0x20, 0xea, 0xa7, 0xde, 0xa2, 0x03, 0x25, 0xad, 0x11, 0x0a, 0xd9, 0x57, 0xd3, 0x0f, 0x88, 0xfa, 0xa9, 0xb7, 0xa8, 0x40, 0x49, 0xeb, 0x84, 0x42, 0x72, 0x23, 0x1e,
0x1b, 0xf1, 0xc0, 0xec, 0xee, 0xe1, 0x03, 0xb2, 0xd1, 0xe6, 0xd9, 0xde, 0x88, 0x07, 0xe6, 0x3a, 0x1a, 0xda, 0x3e, 0x3e, 0x20, 0x89, 0x36, 0xcf, 0x72, 0x23, 0x1e, 0x1a, 0x1b, 0x94, 0x40, 0xb2,
0x25, 0x90, 0x5d, 0xde, 0xc1, 0x24, 0x0f, 0xb0, 0x3e, 0x63, 0x28, 0x5e, 0xd6, 0x03, 0x42, 0x90, 0xbc, 0x8d, 0x49, 0x1d, 0x60, 0x7e, 0xc6, 0x50, 0xbc, 0xac, 0xfa, 0x04, 0xbf, 0x32, 0x28, 0xca,
0x19, 0x14, 0xe5, 0xcc, 0x60, 0x09, 0x80, 0x68, 0xaa, 0x7b, 0xd0, 0x33, 0x0e, 0x5d, 0x9a, 0x48, 0x95, 0xc1, 0x32, 0x00, 0xd1, 0x94, 0x76, 0xd0, 0xd7, 0x0f, 0x1d, 0x5a, 0x48, 0x97, 0xd4, 0x0a,
0x97, 0xf4, 0x0a, 0xa1, 0xdc, 0x25, 0x04, 0x0a, 0xd3, 0xe1, 0xd5, 0x05, 0xda, 0xbf, 0x1d, 0x4e, 0xa1, 0xdc, 0x25, 0x04, 0x0a, 0xd3, 0xc1, 0xdd, 0xf9, 0xda, 0xbf, 0x1d, 0x2c, 0x10, 0x6e, 0xf8,
0x10, 0x6e, 0x04, 0x2a, 0x4f, 0xe8, 0xb1, 0x32, 0x26, 0x5d, 0x68, 0x61, 0xc8, 0x8b, 0x64, 0x9d, 0x2a, 0x4f, 0x98, 0xb1, 0x3a, 0xa1, 0x5c, 0x68, 0x63, 0xc8, 0x8b, 0x62, 0x9d, 0xba, 0x48, 0x46,
0xba, 0x48, 0x46, 0x72, 0x91, 0x93, 0x05, 0xde, 0x22, 0x54, 0x2c, 0xb7, 0xcb, 0xb5, 0x9c, 0xa3, 0x72, 0x91, 0x93, 0x05, 0xde, 0x12, 0x54, 0x4c, 0x47, 0xe3, 0x5a, 0xce, 0xd1, 0x57, 0x94, 0x4d,
0x43, 0x94, 0x2d, 0x77, 0x87, 0xbe, 0x6b, 0x4f, 0x89, 0x4b, 0x29, 0xf2, 0x11, 0xb2, 0xa8, 0x65, 0x67, 0x97, 0x3e, 0x2b, 0x4f, 0x89, 0x4b, 0xc5, 0xd4, 0x23, 0x64, 0x53, 0x2b, 0x50, 0x65, 0x56,
0xa8, 0x32, 0x2b, 0x75, 0xa5, 0xcc, 0x04, 0x18, 0x69, 0x7b, 0x82, 0xfc, 0x64, 0x91, 0x60, 0x9d, 0xd2, 0xa4, 0xca, 0x04, 0x18, 0x69, 0x67, 0x8a, 0xfa, 0x64, 0x89, 0x60, 0x5d, 0x5c, 0x65, 0xf2,
0x2a, 0x33, 0x79, 0xd0, 0x33, 0xb5, 0x79, 0x40, 0x3b, 0x8e, 0xfd, 0x5d, 0xbc, 0x2f, 0x07, 0xb5, 0xa0, 0x6f, 0x28, 0x0b, 0x80, 0x76, 0x6d, 0xeb, 0x3b, 0xb8, 0x27, 0x07, 0xb5, 0xf2, 0x0e, 0xcc,
0xf6, 0x0e, 0xcc, 0x85, 0xa8, 0x3c, 0xff, 0xba, 0x02, 0xb5, 0x21, 0x23, 0x77, 0x5d, 0xa3, 0x27, 0x07, 0xa8, 0xbc, 0xfe, 0xba, 0x02, 0xb5, 0x11, 0x23, 0x6b, 0x8e, 0xde, 0x17, 0x3e, 0x54, 0xe5,
0x7c, 0xa8, 0xca, 0x69, 0xbb, 0x46, 0xcf, 0xd3, 0x7e, 0x5c, 0x82, 0xe2, 0x83, 0x3d, 0xf2, 0x9a, 0xb4, 0x3d, 0xbd, 0xef, 0x2a, 0x3f, 0x2a, 0x41, 0xf1, 0xc1, 0x3e, 0x79, 0x4c, 0xf4, 0xb5, 0xeb,
0xe8, 0x6b, 0xd7, 0x61, 0x26, 0xd8, 0xe6, 0xa5, 0xb8, 0x9b, 0xf6, 0xa9, 0x3b, 0x3c, 0x00, 0x3f, 0x30, 0xe7, 0xa7, 0x79, 0x29, 0xee, 0x66, 0x3d, 0xea, 0x2e, 0x0f, 0xc0, 0xcf, 0xb0, 0xed, 0xf8,
0xc3, 0x8e, 0x1b, 0xa4, 0x87, 0xe2, 0x15, 0xdd, 0x82, 0xa2, 0xeb, 0x19, 0xde, 0xc8, 0xa5, 0xfe, 0xe5, 0xa1, 0x78, 0x44, 0xb7, 0xa0, 0xe8, 0xb8, 0xba, 0x3b, 0x76, 0xa8, 0xbf, 0x91, 0xe3, 0x8a,
0x46, 0x8e, 0x2b, 0xbe, 0x99, 0xd9, 0xd0, 0x2b, 0xbb, 0xb4, 0x59, 0xe7, 0x6c, 0xe8, 0x4d, 0xa8, 0x67, 0x66, 0xf6, 0xea, 0xd5, 0x3d, 0x3a, 0xac, 0x72, 0x36, 0xf4, 0x26, 0x54, 0x1c, 0xd7, 0xc6,
0xb8, 0x9e, 0x83, 0x8d, 0x3e, 0xd1, 0x4f, 0x81, 0x06, 0x52, 0x83, 0x07, 0x52, 0x79, 0x97, 0x36, 0xfa, 0x80, 0xe8, 0xa7, 0x40, 0x03, 0xa9, 0xc1, 0x03, 0xa9, 0xbc, 0x47, 0x07, 0xba, 0x1d, 0xb5,
0x74, 0xda, 0x7a, 0x99, 0xb1, 0x74, 0xcc, 0xc8, 0x21, 0xac, 0x78, 0xba, 0xf3, 0xef, 0x1a, 0x19, 0xcc, 0x58, 0xba, 0x46, 0xe8, 0x10, 0x56, 0x3c, 0xdd, 0xf9, 0x77, 0x9d, 0xbc, 0x93, 0xbc, 0x9d,
0x93, 0x8c, 0x4e, 0x64, 0x94, 0x4e, 0x20, 0xa3, 0xcc, 0xba, 0xad, 0x91, 0xb4, 0x8f, 0xa5, 0x27, 0xc8, 0x28, 0x9d, 0x40, 0x46, 0x99, 0x4d, 0x5b, 0x27, 0x65, 0x1f, 0x2b, 0x4f, 0x30, 0x95, 0x51,
0x98, 0xca, 0x28, 0x9f, 0x64, 0x1e, 0xbc, 0xdf, 0x9a, 0x87, 0xee, 0x41, 0x33, 0xd0, 0x36, 0xd1, 0x3e, 0xc9, 0x3a, 0xf8, 0xbc, 0x75, 0x17, 0xdd, 0x83, 0x96, 0xaf, 0x6d, 0xa2, 0x27, 0x43, 0x77,
0x93, 0x69, 0x78, 0x46, 0x77, 0x60, 0x0f, 0xf6, 0x71, 0xb3, 0x42, 0x55, 0x31, 0xcd, 0x55, 0x51, 0x75, 0x6d, 0x68, 0x0d, 0x7b, 0xb8, 0x55, 0xa1, 0xaa, 0x98, 0xe5, 0xaa, 0x28, 0xec, 0x10, 0xa2,
0xd8, 0x26, 0x44, 0x7d, 0xc1, 0x67, 0xdf, 0xe2, 0xdc, 0x94, 0x8e, 0xde, 0x04, 0x14, 0x17, 0xd4, 0xba, 0xe8, 0xb1, 0x6f, 0x73, 0x6e, 0x4a, 0x47, 0x6f, 0x02, 0x8a, 0x0a, 0x6a, 0x01, 0x35, 0x5d,
0x04, 0x6a, 0xba, 0xd9, 0x58, 0x1f, 0xf4, 0x06, 0xa0, 0x03, 0xeb, 0x38, 0x9a, 0xc8, 0x55, 0x29, 0x33, 0x32, 0x07, 0xbd, 0x01, 0xe8, 0xc0, 0x3c, 0x0e, 0x17, 0x72, 0x55, 0x0a, 0xa5, 0x0d, 0x3a,
0x94, 0x36, 0x68, 0x8b, 0x9c, 0xc1, 0x6d, 0xc2, 0x6c, 0xfc, 0x48, 0x58, 0x1b, 0x9f, 0x42, 0x36, 0x22, 0x57, 0x70, 0x5b, 0xd0, 0x8c, 0x1e, 0x09, 0x6b, 0x93, 0x4b, 0xc8, 0x86, 0x1d, 0x3e, 0x0b,
0x9c, 0xe8, 0x59, 0xf0, 0x11, 0x9c, 0x53, 0x9f, 0x01, 0xa7, 0x27, 0x3c, 0x03, 0xce, 0xe3, 0x84, 0x3e, 0x82, 0x73, 0xf1, 0x67, 0xc0, 0xd9, 0x29, 0xcf, 0x80, 0x0b, 0x38, 0xe1, 0xf0, 0xe7, 0x5a,
0xc3, 0x9f, 0x67, 0x7b, 0x46, 0x8f, 0x2d, 0x63, 0x86, 0x2e, 0xa3, 0x42, 0x29, 0x74, 0xfe, 0xcb, 0xae, 0xde, 0x67, 0xdb, 0x98, 0xa3, 0xdb, 0xa8, 0x50, 0x0a, 0x5d, 0xff, 0x0a, 0x54, 0xcd, 0x61,
0x50, 0xb5, 0x06, 0x3d, 0x6b, 0x80, 0x59, 0x7b, 0x9d, 0xb6, 0x03, 0x23, 0x09, 0x06, 0x07, 0xf7, 0xdf, 0x1c, 0x62, 0x36, 0x5e, 0xa7, 0xe3, 0xc0, 0x48, 0x82, 0xc1, 0xc6, 0x03, 0xcb, 0xe5, 0x0c,
0x6d, 0x8f, 0x33, 0x34, 0x18, 0x03, 0x23, 0x11, 0x06, 0xed, 0x23, 0x28, 0x32, 0xaf, 0x45, 0x55, 0x0d, 0xc6, 0xc0, 0x48, 0x84, 0x41, 0xf9, 0x08, 0x8a, 0xcc, 0x6b, 0x51, 0x15, 0x4a, 0xdd, 0x9d,
0x28, 0x75, 0xb6, 0x3f, 0x5e, 0xbb, 0xdf, 0x69, 0x37, 0xa6, 0xd0, 0x34, 0x54, 0x1e, 0xed, 0xdc, 0x8f, 0xd7, 0xef, 0x77, 0x3b, 0x8d, 0x19, 0x34, 0x0b, 0x95, 0x47, 0xbb, 0xf7, 0x1f, 0xac, 0x77,
0x7f, 0xb0, 0xd6, 0xee, 0x6c, 0xdf, 0x6b, 0x64, 0xd0, 0x0c, 0xc0, 0x9d, 0x07, 0x5b, 0x5b, 0x9d, 0xba, 0x3b, 0xf7, 0x1a, 0x19, 0x34, 0x07, 0x70, 0xe7, 0xc1, 0xf6, 0x76, 0xf7, 0xe1, 0x43, 0xf2,
0x87, 0x0f, 0xc9, 0x7b, 0x96, 0x34, 0xf3, 0xf7, 0x8d, 0x76, 0x23, 0x87, 0x6a, 0x50, 0x6e, 0x6f, 0x9c, 0x25, 0xc3, 0xfc, 0x79, 0xb3, 0xd3, 0xc8, 0xa1, 0x1a, 0x94, 0x3b, 0x9b, 0xf7, 0x37, 0xe9,
0xdc, 0xdf, 0xa0, 0x8d, 0x79, 0xed, 0x4f, 0x59, 0x40, 0x2c, 0x20, 0xd6, 0xf1, 0xa1, 0x35, 0x90, 0x60, 0x5e, 0xf9, 0x63, 0x16, 0x10, 0x0b, 0x88, 0x0d, 0x7c, 0x68, 0x0e, 0xa5, 0x73, 0xda, 0xcb,
0xce, 0x69, 0x2f, 0x27, 0x2e, 0xc3, 0xfe, 0x9a, 0x3f, 0x9d, 0xbf, 0x2a, 0x3d, 0xa1, 0x74, 0xa6, 0x89, 0xcb, 0xa0, 0xbf, 0xe6, 0x4f, 0xe7, 0xaf, 0xb1, 0x9e, 0x50, 0x3a, 0x53, 0x4f, 0x28, 0xbf,
0x9e, 0x50, 0x7e, 0x11, 0x4f, 0xd0, 0x7e, 0x93, 0x85, 0xb9, 0x90, 0x56, 0x39, 0x38, 0xbe, 0x34, 0x88, 0x27, 0x28, 0xbf, 0xce, 0xc2, 0x7c, 0x40, 0xab, 0x1c, 0x1c, 0x5f, 0x9a, 0x5a, 0x03, 0xe8,
0xb5, 0x86, 0xd0, 0x2b, 0x3f, 0x16, 0xbd, 0x94, 0x0a, 0x2c, 0x9c, 0xa9, 0x02, 0x8b, 0x2f, 0xa4, 0x95, 0x9f, 0x88, 0x5e, 0xb1, 0x0a, 0x2c, 0x9c, 0xa9, 0x02, 0x8b, 0x2f, 0xa4, 0xc0, 0x5f, 0x65,
0xc0, 0x5f, 0x67, 0x84, 0x02, 0x43, 0x27, 0x92, 0xf0, 0x3a, 0x33, 0x63, 0xd7, 0x99, 0x06, 0x6c, 0x84, 0x02, 0x03, 0x27, 0x92, 0xe0, 0x3e, 0x33, 0x13, 0xf7, 0x99, 0x06, 0x6c, 0xd9, 0x17, 0x07,
0xd9, 0x17, 0x07, 0xb6, 0x5c, 0x02, 0xb0, 0x69, 0x0b, 0x30, 0x1f, 0x9e, 0x3d, 0x3f, 0xe6, 0x3f, 0xb6, 0x5c, 0x02, 0xb0, 0x29, 0x8b, 0xb0, 0x10, 0x5c, 0x3d, 0x3f, 0xe6, 0x3f, 0x83, 0x06, 0xa3,
0x83, 0x06, 0xa3, 0x4b, 0xd5, 0x9b, 0x97, 0xe5, 0x13, 0xda, 0x7b, 0x30, 0x2b, 0x0d, 0x16, 0x94, 0x4b, 0xdd, 0x9b, 0x97, 0xe5, 0x13, 0xca, 0x7b, 0xd0, 0x94, 0x5e, 0xe6, 0xb7, 0x80, 0x2c, 0x4a,
0x80, 0x6c, 0x4a, 0x8c, 0x97, 0x80, 0x18, 0xb3, 0xce, 0xdb, 0xb5, 0x1f, 0x64, 0x45, 0xff, 0x48, 0x8c, 0xb6, 0x80, 0x18, 0xb3, 0xca, 0xc7, 0x95, 0xef, 0x67, 0xc5, 0xfc, 0x50, 0x03, 0x27, 0x76,
0x01, 0x47, 0x39, 0xdb, 0xd7, 0xa1, 0x21, 0xcd, 0x56, 0x4e, 0x13, 0xeb, 0xc1, 0x7c, 0x59, 0xbe, 0xb5, 0xaf, 0x43, 0x43, 0x5a, 0xad, 0x5c, 0x26, 0xd6, 0xfd, 0xf5, 0xb2, 0x7a, 0x31, 0xc0, 0xca,
0x18, 0x62, 0xe5, 0xd5, 0xa0, 0x5c, 0x84, 0xf5, 0x0e, 0x2b, 0x0b, 0x85, 0x52, 0xc3, 0x7c, 0x62, 0xbb, 0x41, 0xb9, 0x10, 0xeb, 0x1d, 0xd6, 0x16, 0x0a, 0x94, 0x86, 0xf9, 0xc4, 0xd2, 0xb0, 0x20,
0x6a, 0x58, 0x90, 0x53, 0xc3, 0x0e, 0xd4, 0xd9, 0x0a, 0xba, 0xd6, 0x60, 0xbf, 0x37, 0x32, 0x71, 0x97, 0x86, 0x5d, 0xa8, 0xb3, 0x1d, 0x68, 0xe6, 0xb0, 0xd7, 0x1f, 0x1b, 0xd8, 0xf7, 0xc5, 0xd0,
0xe0, 0x8b, 0x91, 0xa5, 0x8a, 0x52, 0x50, 0x87, 0xf3, 0xe9, 0x33, 0xac, 0xa3, 0x78, 0xd7, 0x9e, 0x56, 0x45, 0x2b, 0xa8, 0xcb, 0xf9, 0xd4, 0x39, 0x36, 0x51, 0x3c, 0x2b, 0x4f, 0x04, 0x36, 0x4e,
0x08, 0x6c, 0x9c, 0xb0, 0xc2, 0x14, 0x16, 0x9b, 0x56, 0x61, 0xfa, 0x6d, 0x0e, 0x66, 0xc2, 0xdc, 0xd9, 0x61, 0x0a, 0x8a, 0x4d, 0xeb, 0x30, 0xfd, 0x26, 0x07, 0x73, 0x41, 0xee, 0x18, 0x7b, 0x67,
0x0a, 0x7b, 0x67, 0xc6, 0xd8, 0x3b, 0x9b, 0x94, 0xf2, 0xe4, 0x26, 0x4b, 0x79, 0xc2, 0x39, 0x4c, 0x26, 0xd8, 0x3b, 0x9b, 0x54, 0xf2, 0xe4, 0xa6, 0x2b, 0x79, 0x82, 0x35, 0x4c, 0xfe, 0x0c, 0x6a,
0xfe, 0x0c, 0x72, 0x98, 0xc2, 0x19, 0xe4, 0x30, 0xc5, 0xb3, 0xcf, 0x61, 0x4a, 0x2f, 0x1e, 0xea, 0x98, 0xc2, 0x19, 0xd4, 0x30, 0xc5, 0xb3, 0xaf, 0x61, 0x4a, 0x2f, 0x1e, 0xea, 0xe5, 0xa4, 0x50,
0xe5, 0xa4, 0x50, 0xff, 0x0f, 0x58, 0x50, 0x7b, 0x13, 0x6a, 0x41, 0xd9, 0xef, 0x9e, 0x61, 0xb9, 0xff, 0x77, 0x58, 0x8c, 0xf7, 0x26, 0xd4, 0x86, 0xb2, 0x37, 0x3d, 0xc3, 0x6a, 0x79, 0xf1, 0xac,
0xbc, 0x78, 0xd7, 0x5c, 0x68, 0x4a, 0xfb, 0x43, 0xb8, 0xc8, 0xfa, 0xd2, 0x00, 0xe1, 0x03, 0xb8, 0x38, 0xd0, 0x92, 0xf2, 0x43, 0xb0, 0xc9, 0xfa, 0xd2, 0x00, 0xe1, 0x03, 0xb8, 0x10, 0xf3, 0x52,
0xa0, 0x18, 0x94, 0x7b, 0xf5, 0xc9, 0x90, 0x35, 0x90, 0x75, 0xd7, 0x1a, 0x58, 0xee, 0x51, 0x78, 0xee, 0xd5, 0x27, 0x43, 0x56, 0x5f, 0xd6, 0x5d, 0x73, 0x68, 0x3a, 0x47, 0xc1, 0x1d, 0x9c, 0x50,
0x05, 0x27, 0x94, 0x75, 0x11, 0x5a, 0x2a, 0x59, 0x1c, 0x33, 0xff, 0x91, 0x85, 0xea, 0xae, 0xe1, 0xd6, 0x45, 0x68, 0xc7, 0xc9, 0xe2, 0x98, 0xf9, 0xf7, 0x2c, 0x54, 0xf7, 0x74, 0x57, 0xcc, 0x7b,
0x89, 0x7e, 0x2f, 0x6f, 0x0f, 0x7d, 0xa1, 0xda, 0x64, 0x07, 0xa6, 0x69, 0x4c, 0x90, 0x5d, 0xd0, 0x79, 0x39, 0xf4, 0x85, 0x7a, 0x93, 0x5d, 0x98, 0xa5, 0x31, 0x41, 0xb2, 0xa0, 0xa1, 0xbb, 0xf8,
0x34, 0x3c, 0x7c, 0xa2, 0x50, 0xa8, 0x89, 0xae, 0x6d, 0xc3, 0xc3, 0x68, 0x0b, 0xea, 0x41, 0xc5, 0x44, 0xa1, 0x50, 0x13, 0x53, 0x3b, 0xba, 0x8b, 0xd1, 0x36, 0xd4, 0xfd, 0x8e, 0x23, 0x13, 0x76,
0x91, 0x09, 0x3b, 0x49, 0x4c, 0xcc, 0x04, 0x9d, 0xa9, 0xb8, 0x5b, 0x30, 0xe7, 0x1a, 0x1e, 0xee, 0x92, 0x98, 0x98, 0xf3, 0x27, 0x53, 0x71, 0xb7, 0x60, 0xde, 0xd1, 0x5d, 0xdc, 0xef, 0x9b, 0xb4,
0xf5, 0x2c, 0x9a, 0x58, 0x1e, 0x0e, 0x0c, 0x6f, 0xe4, 0xf0, 0xbc, 0x5e, 0x47, 0x7e, 0xd3, 0xae, 0xb0, 0x3c, 0x1c, 0xea, 0xee, 0xd8, 0xe6, 0x75, 0xbd, 0x8a, 0xbc, 0xa1, 0x3d, 0x31, 0xa2, 0xfc,
0x68, 0xd1, 0xfe, 0x96, 0x85, 0x12, 0xcf, 0xbb, 0x4f, 0xba, 0xdf, 0xfe, 0x27, 0x94, 0x87, 0xb6, 0x35, 0x0b, 0x25, 0x5e, 0x77, 0x9f, 0x34, 0xdf, 0xfe, 0x07, 0x94, 0x47, 0x96, 0x63, 0xba, 0x02,
0x6b, 0x79, 0x02, 0x9d, 0xaa, 0xab, 0x17, 0x02, 0x10, 0xe2, 0x32, 0x77, 0x38, 0x83, 0xee, 0xb3, 0x9d, 0xaa, 0x6b, 0x17, 0x7c, 0x10, 0xe2, 0x32, 0x77, 0x39, 0x83, 0xea, 0xb1, 0xa2, 0xf7, 0x60,
0xa2, 0xf7, 0x60, 0x2e, 0x30, 0xdd, 0x33, 0xfc, 0x9c, 0x87, 0x6d, 0x4e, 0x15, 0xb6, 0x41, 0x08, 0xde, 0x37, 0xdd, 0x33, 0xfc, 0x9c, 0x87, 0x6d, 0x2e, 0x2e, 0x6c, 0xfd, 0x10, 0xfc, 0x10, 0x3f,
0x7e, 0x88, 0x9f, 0xb3, 0x88, 0xbd, 0x0a, 0xd3, 0xa1, 0xee, 0xbc, 0xc4, 0x50, 0x93, 0x39, 0xd1, 0x67, 0x11, 0x7b, 0x15, 0x66, 0x03, 0xd3, 0x79, 0x8b, 0xa1, 0x26, 0x73, 0xa2, 0x55, 0x98, 0x27,
0x0a, 0xcc, 0x91, 0xac, 0x5a, 0xaa, 0x1e, 0xd3, 0xc0, 0x64, 0x55, 0xe3, 0x59, 0xd2, 0xe4, 0x97, 0x55, 0xb5, 0xd4, 0x3d, 0xa6, 0x81, 0xc9, 0xba, 0xc6, 0x4d, 0x32, 0xe4, 0xb5, 0x8d, 0x3b, 0xe4,
0x8d, 0xdb, 0xe4, 0x6c, 0xb2, 0xea, 0x27, 0x36, 0xd8, 0xec, 0xf2, 0xbc, 0x9d, 0xf6, 0x60, 0x97, 0x6c, 0xb2, 0xe6, 0x15, 0x36, 0xd8, 0xd0, 0x78, 0xdd, 0x4e, 0x67, 0xb0, 0x4b, 0x1d, 0x7f, 0xc1,
0x3a, 0xc1, 0x84, 0x3b, 0xb4, 0x8d, 0xf6, 0x79, 0x0d, 0x8a, 0xb4, 0x64, 0xeb, 0x36, 0x4b, 0x74, 0x5d, 0x3a, 0x46, 0xe7, 0xbc, 0x06, 0x45, 0xda, 0xb2, 0x75, 0x5a, 0x25, 0x9a, 0x1a, 0xea, 0xfe,
0x6b, 0xa8, 0x07, 0x8b, 0xa7, 0xb5, 0x18, 0x9d, 0x37, 0x6b, 0x9b, 0x50, 0xa0, 0x04, 0x72, 0xe0, 0xe6, 0x69, 0x2f, 0x46, 0xe5, 0xc3, 0xca, 0x16, 0x14, 0x28, 0x81, 0x1c, 0xf8, 0x59, 0x93, 0x77,
0x67, 0x45, 0xde, 0xc1, 0xa8, 0x4f, 0xf5, 0x5b, 0xd0, 0xcb, 0x94, 0xb0, 0x3d, 0xea, 0x23, 0x0d, 0x38, 0x1e, 0x50, 0xfd, 0x16, 0xd4, 0x32, 0x25, 0xec, 0x8c, 0x07, 0x48, 0x81, 0xfc, 0xd0, 0x32,
0xf2, 0x03, 0xdb, 0x14, 0x99, 0xca, 0x0c, 0xd7, 0x43, 0x71, 0xdb, 0x36, 0x71, 0xa7, 0xad, 0xd3, 0x44, 0xa5, 0x32, 0xc7, 0xf5, 0x50, 0xdc, 0xb1, 0x0c, 0xdc, 0xed, 0xa8, 0x74, 0x4c, 0xd9, 0x82,
0x36, 0x6d, 0x13, 0xea, 0x11, 0xbd, 0x92, 0x63, 0x04, 0x39, 0xd8, 0x13, 0x91, 0x7b, 0xbc, 0xd2, 0x7a, 0x48, 0xaf, 0xe4, 0x18, 0x41, 0x0e, 0xf6, 0x44, 0xe4, 0x3e, 0xef, 0x74, 0x16, 0x54, 0x7a,
0x59, 0xd0, 0xe9, 0xe9, 0x7f, 0x9b, 0x52, 0xc8, 0xbe, 0x69, 0x0d, 0x4c, 0x7c, 0x2c, 0x2e, 0x5b, 0xfa, 0xdf, 0xa1, 0x14, 0x92, 0x37, 0xcd, 0xa1, 0x81, 0x8f, 0xc5, 0x65, 0x0b, 0x7d, 0x50, 0x7e,
0xe8, 0x8b, 0xf6, 0xf3, 0x0c, 0xcc, 0x71, 0x51, 0xa1, 0xa3, 0xc0, 0xab, 0x71, 0x81, 0x1b, 0x50, 0x96, 0x81, 0x79, 0x2e, 0x2a, 0x70, 0x14, 0x78, 0x35, 0x2e, 0x70, 0x03, 0xea, 0x03, 0xfd, 0x58,
0xef, 0x1b, 0xc7, 0x5d, 0x5a, 0xdf, 0x65, 0x35, 0x31, 0x5e, 0x52, 0x9b, 0xee, 0x1b, 0xc7, 0x41, 0xa3, 0xfd, 0x5d, 0xd6, 0x13, 0xe3, 0x2d, 0xb5, 0xd9, 0x81, 0x7e, 0xec, 0xb7, 0xc0, 0x94, 0xdf,
0x09, 0x4c, 0xfb, 0x43, 0x06, 0xe6, 0xc3, 0xb3, 0xe4, 0xf8, 0xf5, 0x16, 0x80, 0x38, 0x45, 0xfa, 0x67, 0x60, 0x21, 0xb8, 0x4a, 0x8e, 0x5f, 0x6f, 0x01, 0x88, 0x53, 0xa4, 0xb7, 0xce, 0x26, 0x5f,
0xf3, 0x9c, 0xe5, 0xf3, 0xac, 0x88, 0xa2, 0x61, 0x5b, 0xaf, 0x70, 0xa6, 0x8e, 0xba, 0x0c, 0x97, 0x67, 0x45, 0x34, 0x0d, 0x3b, 0x6a, 0x85, 0x33, 0x75, 0xe3, 0xdb, 0x70, 0xd9, 0xb3, 0x68, 0xc3,
0x3d, 0x8b, 0x32, 0xdc, 0x09, 0xea, 0xa5, 0xbf, 0xc8, 0xfa, 0xcb, 0x09, 0x27, 0xba, 0x27, 0x5f, 0x9d, 0xa0, 0x5f, 0xfa, 0xf3, 0xac, 0xb7, 0x9d, 0x60, 0xa1, 0x7b, 0xf2, 0xed, 0x24, 0x04, 0x51,
0x4e, 0x42, 0x10, 0x65, 0x4f, 0x1b, 0x44, 0xb9, 0xc9, 0x83, 0x28, 0x9f, 0x14, 0x44, 0xf7, 0x60, 0xf6, 0xb4, 0x41, 0x94, 0x9b, 0x3e, 0x88, 0xf2, 0x49, 0x41, 0x74, 0x0f, 0x66, 0xc7, 0xa3, 0xbe,
0x7a, 0x34, 0xec, 0xd9, 0x86, 0xd9, 0x75, 0xb0, 0x3b, 0xea, 0x79, 0xbc, 0x8e, 0xaf, 0xc5, 0x3d, 0xa5, 0x1b, 0x9a, 0x8d, 0x9d, 0x71, 0xdf, 0xe5, 0x7d, 0x7c, 0x25, 0xea, 0x11, 0x44, 0x47, 0x8f,
0x82, 0xe8, 0xe8, 0xd1, 0x90, 0x17, 0xc0, 0x47, 0x3d, 0x4f, 0xaf, 0x8d, 0xa4, 0x37, 0xed, 0x47, 0x46, 0xbc, 0x01, 0x3e, 0xee, 0xbb, 0x6a, 0x6d, 0x2c, 0x3d, 0x29, 0x3f, 0xf4, 0xfb, 0xa9, 0x11,
0x41, 0x3d, 0x35, 0xc6, 0x9a, 0x1e, 0x44, 0xaf, 0x41, 0x89, 0xde, 0x87, 0xf9, 0xb7, 0x28, 0xd1, 0xd6, 0xf4, 0x20, 0x7a, 0x0d, 0x4a, 0xf4, 0x3e, 0xcc, 0xbb, 0x45, 0x09, 0xc7, 0x51, 0x91, 0x0c,
0x38, 0x2a, 0x92, 0xe6, 0x8e, 0x89, 0xae, 0x43, 0xfe, 0xc8, 0x70, 0x8f, 0xf8, 0xb7, 0x0c, 0xb3, 0x77, 0x0d, 0x74, 0x1d, 0xf2, 0x47, 0xba, 0x73, 0xc4, 0xff, 0xcb, 0xd0, 0x14, 0x57, 0x0d, 0xf4,
0xe2, 0xaa, 0x81, 0x0e, 0xb7, 0x69, 0xb8, 0x47, 0x3a, 0x6d, 0xd6, 0xfe, 0x95, 0x85, 0x1a, 0xd9, 0x75, 0x5b, 0xba, 0x73, 0xa4, 0xd2, 0x61, 0xe5, 0x9f, 0x59, 0xa8, 0x91, 0x74, 0x24, 0x4c, 0x80,
0x8e, 0x84, 0x09, 0xd0, 0x6a, 0x34, 0x3e, 0xaa, 0xab, 0xe7, 0xa4, 0xf5, 0x05, 0x3b, 0x97, 0x14, 0xd6, 0xc2, 0xf1, 0x51, 0x5d, 0x3b, 0x27, 0xed, 0xcf, 0xcf, 0x5c, 0x52, 0x90, 0x84, 0x42, 0x34,
0x24, 0x91, 0x10, 0xcd, 0x26, 0x87, 0x68, 0x4e, 0x0a, 0xd1, 0xf8, 0xbd, 0x50, 0x61, 0x82, 0x7b, 0x9b, 0x1c, 0xa2, 0x39, 0x29, 0x44, 0xa3, 0xf7, 0x42, 0x85, 0x29, 0xee, 0x85, 0x3e, 0x82, 0x73,
0xa1, 0x8f, 0xe0, 0x9c, 0x7f, 0x9b, 0x22, 0x85, 0x17, 0xc9, 0x8a, 0x27, 0xf0, 0xf5, 0x39, 0xd1, 0xde, 0x6d, 0x8a, 0x14, 0x5e, 0xa4, 0x2a, 0x9e, 0xc2, 0xd7, 0xe7, 0xc5, 0x5c, 0x9f, 0xe6, 0x44,
0x37, 0xa0, 0xb9, 0xf1, 0xcd, 0xae, 0x74, 0xea, 0xcd, 0x2e, 0x61, 0x77, 0x2a, 0x27, 0xee, 0x4e, 0x93, 0x5d, 0xe9, 0xd4, 0xc9, 0x2e, 0x21, 0x3b, 0x95, 0x13, 0xb3, 0x53, 0xc7, 0xbb, 0x61, 0x08,
0xe7, 0xfd, 0x1b, 0x86, 0xc8, 0xd9, 0xea, 0x67, 0x59, 0xdf, 0x45, 0xb6, 0x8c, 0x67, 0x98, 0xc1, 0x9e, 0xad, 0xd0, 0xbf, 0x41, 0xd3, 0x19, 0xf7, 0x7a, 0xd8, 0x71, 0x0e, 0xc6, 0x7d, 0x8d, 0xe3,
0xf2, 0xab, 0x05, 0xb1, 0x57, 0xb1, 0x8f, 0x25, 0xee, 0x4b, 0x85, 0xc4, 0x7d, 0x89, 0x55, 0x77, 0x30, 0xf3, 0x86, 0x86, 0x3f, 0xb0, 0xcb, 0x00, 0xf8, 0xa7, 0x59, 0xcf, 0x9f, 0xb6, 0xf5, 0x67,
0x63, 0x9a, 0xe1, 0x7a, 0xb3, 0xfd, 0x46, 0x45, 0x2e, 0xba, 0x18, 0xd3, 0xdb, 0x0b, 0x6b, 0x49, 0x98, 0x61, 0xf8, 0xab, 0x45, 0xbc, 0x57, 0x91, 0xf4, 0x12, 0x93, 0x58, 0x21, 0x31, 0x89, 0xb1,
0xfb, 0x2a, 0xb8, 0xf4, 0x52, 0x25, 0xa2, 0xdf, 0x4e, 0x20, 0xff, 0x49, 0xb0, 0x28, 0x55, 0x46, 0x56, 0x70, 0x44, 0x33, 0xbc, 0x18, 0xb3, 0xbc, 0xc1, 0x98, 0xc2, 0x75, 0x29, 0xa2, 0xb7, 0x17,
0x7c, 0xf2, 0x45, 0xdd, 0x86, 0x12, 0xc3, 0x4c, 0xb1, 0x96, 0x04, 0xd0, 0xf4, 0xb5, 0x47, 0x40, 0xd6, 0x92, 0xf2, 0x95, 0x7f, 0x43, 0x16, 0x57, 0xb5, 0x7e, 0x3b, 0x51, 0xff, 0xc7, 0xfe, 0xa6,
0x53, 0x74, 0x89, 0xe1, 0xa5, 0xcc, 0xf5, 0x6a, 0xf1, 0x72, 0x09, 0x16, 0x95, 0x7a, 0xe1, 0xde, 0xe2, 0xca, 0xe7, 0x93, 0x6f, 0xea, 0x36, 0x94, 0x18, 0xc0, 0x8a, 0xbd, 0x24, 0x20, 0xac, 0xa7,
0xf7, 0x45, 0x06, 0x10, 0x6f, 0x97, 0xcb, 0x0c, 0xa9, 0x7e, 0xb7, 0x0e, 0x75, 0x56, 0x36, 0xe8, 0x3d, 0x82, 0xb0, 0x62, 0x4a, 0x04, 0x5c, 0x65, 0xae, 0x57, 0x0b, 0xae, 0xcb, 0xb0, 0x14, 0xab,
0x4e, 0xee, 0x7e, 0x33, 0xac, 0x87, 0x9f, 0x24, 0xf9, 0xb5, 0x83, 0x9c, 0x54, 0x3b, 0xd0, 0x9e, 0x17, 0xee, 0x7d, 0x5f, 0x64, 0x00, 0xf1, 0x71, 0xb9, 0x27, 0x91, 0xea, 0x77, 0x1b, 0x50, 0x67,
0xfa, 0x29, 0x50, 0xe8, 0xc4, 0x7f, 0x2b, 0x7c, 0xe2, 0x8f, 0x0f, 0x33, 0xc9, 0x91, 0x3f, 0xc8, 0x3d, 0x06, 0x6d, 0x7a, 0xf7, 0x9b, 0x63, 0x33, 0xbc, 0x8a, 0xca, 0x6b, 0x34, 0xe4, 0xa4, 0x46,
0xd4, 0xfc, 0x23, 0xbf, 0x1c, 0x40, 0x99, 0xc9, 0x03, 0xe8, 0x8b, 0x8c, 0x7f, 0x0d, 0x1a, 0xb9, 0x83, 0xf2, 0xd4, 0xab, 0x97, 0x02, 0xed, 0x81, 0x5b, 0xc1, 0xf6, 0x40, 0xf4, 0x35, 0xd3, 0xf4,
0x99, 0x3e, 0x29, 0xce, 0x9d, 0x81, 0x26, 0xb5, 0x5f, 0xe5, 0x82, 0xcb, 0xd4, 0xc8, 0x1d, 0xf6, 0x07, 0xfc, 0xb2, 0xce, 0xeb, 0x0f, 0xc8, 0x01, 0x94, 0x99, 0x3e, 0x80, 0xbe, 0xc8, 0x78, 0x77,
0xb7, 0x33, 0x96, 0x93, 0x21, 0x36, 0x9f, 0x9c, 0xfa, 0x5f, 0x81, 0x9a, 0xe2, 0x6b, 0x94, 0xaa, 0xa6, 0xa1, 0x6b, 0xec, 0x93, 0xe2, 0xdc, 0x19, 0x68, 0x52, 0xf9, 0x65, 0xce, 0xbf, 0x79, 0x0d,
0x2b, 0xdd, 0x5f, 0x24, 0xec, 0x0e, 0xc5, 0xd3, 0xee, 0x0e, 0x25, 0xc5, 0xee, 0xf0, 0x26, 0xe4, 0x5d, 0x78, 0x7f, 0x3b, 0x63, 0x39, 0x19, 0x62, 0xf3, 0xc9, 0xe7, 0x84, 0x2b, 0x50, 0x8b, 0xf9,
0x07, 0xf8, 0x58, 0x5c, 0x04, 0xa5, 0x58, 0x91, 0xb2, 0x69, 0x77, 0xa1, 0xb6, 0x6e, 0x78, 0xfb, 0xeb, 0x4a, 0xd5, 0x91, 0x2e, 0x3b, 0x12, 0xb2, 0x43, 0xf1, 0xb4, 0xd9, 0xa1, 0x14, 0x93, 0x1d,
0x47, 0xc2, 0x7d, 0xfe, 0x0b, 0xca, 0x0e, 0x7b, 0x14, 0xbe, 0xde, 0x92, 0xbe, 0x9f, 0x92, 0x38, 0xde, 0x84, 0xfc, 0x10, 0x1f, 0x8b, 0x5b, 0xa3, 0x14, 0x2b, 0x52, 0x36, 0xe5, 0x2e, 0xd4, 0x36,
0xa9, 0xb3, 0xfb, 0xbc, 0xda, 0xdf, 0x01, 0x1a, 0xd1, 0x66, 0xd4, 0x86, 0x69, 0x7e, 0x27, 0xc9, 0x74, 0xb7, 0x77, 0x24, 0xdc, 0xe7, 0x3f, 0xa1, 0x6c, 0xb3, 0x9f, 0xc2, 0xd7, 0xdb, 0xd2, 0x9f,
0xaa, 0x45, 0xdc, 0xc5, 0x97, 0xa2, 0x5f, 0x64, 0x85, 0x3e, 0x40, 0xdc, 0x9c, 0xd2, 0x6b, 0x7b, 0xad, 0x24, 0x4e, 0xea, 0xec, 0x1e, 0xaf, 0xf2, 0x37, 0x80, 0x46, 0x78, 0x18, 0x75, 0x60, 0x96,
0x12, 0x99, 0x9c, 0xca, 0xb9, 0x94, 0x43, 0x1c, 0x7c, 0xed, 0x18, 0x11, 0x11, 0x94, 0x53, 0x37, 0x5f, 0x60, 0xb2, 0xd6, 0x12, 0x77, 0xf1, 0xe5, 0xf0, 0xdf, 0xb7, 0x02, 0xff, 0x56, 0xdc, 0x9a,
0xa7, 0xf4, 0xca, 0x9e, 0xa0, 0x49, 0x53, 0x30, 0x29, 0xec, 0x70, 0xb0, 0x8a, 0x4d, 0x21, 0x04, 0x51, 0x6b, 0xfb, 0x12, 0x99, 0x1c, 0xe1, 0xb9, 0x94, 0x43, 0xec, 0xff, 0x35, 0x32, 0x24, 0xc2,
0xd6, 0xc1, 0x14, 0x18, 0x19, 0xfd, 0x8f, 0x7f, 0xb9, 0xda, 0xb3, 0x5c, 0xcf, 0xaf, 0x0c, 0x28, 0xef, 0xbd, 0x6e, 0xcd, 0xa8, 0x95, 0x7d, 0x41, 0x93, 0x96, 0x60, 0x50, 0xd8, 0xe1, 0x60, 0x15,
0x3e, 0x2c, 0x0b, 0x24, 0xf0, 0x49, 0x13, 0x22, 0xfa, 0x14, 0x16, 0x78, 0x7f, 0x17, 0x7b, 0x5d, 0x59, 0x42, 0x00, 0xac, 0xfd, 0x25, 0x30, 0x32, 0xfa, 0x6f, 0xef, 0x26, 0xb6, 0x6f, 0x3a, 0xae,
0x23, 0xb8, 0x64, 0xe5, 0x45, 0x82, 0xeb, 0x51, 0x51, 0xca, 0x6b, 0xde, 0xcd, 0x29, 0x7d, 0x7e, 0xd7, 0x46, 0x88, 0xf9, 0x17, 0x9a, 0x2f, 0x81, 0x2f, 0x9a, 0x10, 0xd1, 0xa7, 0xb0, 0xc8, 0xe7,
0x4f, 0xd1, 0x8c, 0xd6, 0xa0, 0xc6, 0x0b, 0x9e, 0x7b, 0x64, 0x3b, 0xe5, 0xc5, 0x82, 0x8b, 0xd1, 0x3b, 0xd8, 0xd5, 0x74, 0xff, 0x46, 0x96, 0x77, 0x14, 0xae, 0x87, 0x45, 0xc5, 0xde, 0x09, 0x6f,
0xea, 0x9f, 0x7c, 0xa8, 0xdb, 0x9c, 0xd2, 0xab, 0x76, 0x40, 0x25, 0x7a, 0xe2, 0x22, 0xf6, 0x69, 0xcd, 0xa8, 0x0b, 0xfb, 0x31, 0xc3, 0x68, 0x1d, 0x6a, 0xbc, 0x3b, 0xba, 0x4f, 0xd2, 0x29, 0xef,
0x52, 0xc5, 0x13, 0xba, 0xa5, 0xa8, 0x8c, 0xd0, 0x19, 0x85, 0xe8, 0xc9, 0x96, 0xc8, 0xc4, 0x54, 0x2c, 0x5c, 0x0c, 0xb7, 0x0a, 0xe5, 0x13, 0xe0, 0xd6, 0x8c, 0x5a, 0xb5, 0x7c, 0x2a, 0xd1, 0x13,
0x5c, 0x0a, 0x31, 0x55, 0x39, 0x6a, 0xaa, 0x68, 0xe5, 0x9b, 0x98, 0xca, 0x16, 0x34, 0xa2, 0x64, 0x17, 0xd1, 0xa3, 0x15, 0x18, 0xaf, 0xfe, 0x96, 0xc3, 0x32, 0x02, 0x07, 0x1a, 0xa2, 0x27, 0x4b,
0xde, 0x99, 0x2a, 0xb9, 0x12, 0x55, 0x72, 0xac, 0x14, 0x4d, 0x94, 0x6c, 0xfb, 0x44, 0xf4, 0x10, 0x22, 0x13, 0x53, 0x71, 0x29, 0xc4, 0x54, 0xe5, 0xb0, 0xa9, 0xc2, 0x6d, 0x72, 0x62, 0x2a, 0x4b,
0xe6, 0x64, 0x2d, 0x08, 0x83, 0x03, 0x95, 0xa3, 0x29, 0x95, 0x11, 0xb5, 0xfa, 0xac, 0x1d, 0x6d, 0xd0, 0x88, 0x92, 0xf9, 0x64, 0xaa, 0xe4, 0x4a, 0x58, 0xc9, 0x91, 0xbe, 0x35, 0x51, 0xb2, 0xe5,
0x43, 0x8f, 0x61, 0x9e, 0x4b, 0x3d, 0xa0, 0xbb, 0x97, 0x10, 0x5b, 0xa5, 0x62, 0xaf, 0x46, 0xc5, 0x11, 0xd1, 0x43, 0x98, 0x97, 0xb5, 0x20, 0x0c, 0x0e, 0x54, 0x8e, 0x12, 0xab, 0x8c, 0xb0, 0xd5,
0x2a, 0xb6, 0xfe, 0xcd, 0x29, 0x1d, 0xd9, 0xb1, 0x46, 0xa2, 0x71, 0x81, 0x17, 0xcc, 0x6a, 0xb5, 0x9b, 0x56, 0x78, 0x0c, 0x3d, 0x86, 0x05, 0x2e, 0xf5, 0x80, 0x66, 0x2f, 0x21, 0xb6, 0x4a, 0xc5,
0xa8, 0xc6, 0x15, 0x67, 0x71, 0xa2, 0x71, 0x57, 0x22, 0xa3, 0x7b, 0x30, 0x23, 0xa4, 0x70, 0xc3, 0x5e, 0x0d, 0x8b, 0x8d, 0x49, 0xfd, 0x5b, 0x33, 0x2a, 0xb2, 0x22, 0x83, 0x44, 0xe3, 0x02, 0x2f,
0xb1, 0x1b, 0xcc, 0x4b, 0x31, 0x31, 0x51, 0xcb, 0x89, 0xd1, 0xb9, 0xe9, 0x1e, 0xc2, 0x9c, 0x10, 0x98, 0xd5, 0x6a, 0x61, 0x8d, 0xc7, 0x1c, 0xdc, 0x89, 0xc6, 0x1d, 0x89, 0x8c, 0xee, 0xc1, 0x9c,
0xd4, 0x37, 0x9e, 0x61, 0x8e, 0x7a, 0xf4, 0x0e, 0x53, 0x95, 0x79, 0xc4, 0x12, 0x6c, 0xa2, 0x3d, 0x90, 0xc2, 0x0d, 0xc7, 0xae, 0x3b, 0x2f, 0x45, 0xc4, 0x84, 0x2d, 0x27, 0xde, 0xce, 0x4d, 0xf7,
0x37, 0xda, 0x46, 0xb4, 0x17, 0x5a, 0xa4, 0xd0, 0x5e, 0x3d, 0xaa, 0xbd, 0xc4, 0x04, 0x94, 0x68, 0x10, 0xe6, 0x85, 0xa0, 0x81, 0xfe, 0x0c, 0x73, 0xd4, 0xa3, 0x17, 0x9e, 0x71, 0x95, 0x47, 0xa4,
0xcf, 0x8d, 0x35, 0xa2, 0xa7, 0x70, 0x4e, 0x08, 0x0e, 0xdb, 0xa5, 0x41, 0x25, 0x5f, 0x8b, 0x49, 0xc0, 0x26, 0xda, 0x73, 0xc2, 0x63, 0x44, 0x7b, 0x81, 0x4d, 0x0a, 0xed, 0xd5, 0xc3, 0xda, 0x4b,
0x56, 0x1b, 0x46, 0xac, 0x39, 0x64, 0x99, 0xb5, 0x00, 0xc9, 0xa9, 0x27, 0xce, 0x46, 0xc3, 0x29, 0x2c, 0x40, 0x89, 0xf6, 0x9c, 0xc8, 0x20, 0x7a, 0x0a, 0xe7, 0x84, 0xe0, 0xa0, 0x5d, 0x1a, 0x54,
0x9e, 0xae, 0x90, 0x70, 0x72, 0x03, 0x2a, 0xda, 0x82, 0x86, 0x10, 0x61, 0xf2, 0x2d, 0xb1, 0x89, 0xf2, 0xb5, 0x88, 0xe4, 0x78, 0xc3, 0x88, 0x3d, 0x07, 0x2c, 0xb3, 0xee, 0x23, 0x39, 0xf5, 0xc4,
0xa2, 0x77, 0x10, 0xea, 0x1d, 0x7c, 0x73, 0x4a, 0xaf, 0xbb, 0xe1, 0x96, 0xf5, 0x0a, 0x94, 0xc4, 0x66, 0x38, 0x9c, 0xa2, 0xe5, 0x0a, 0x09, 0x27, 0xc7, 0xa7, 0xa2, 0x6d, 0x68, 0x08, 0x11, 0x06,
0x47, 0x17, 0x1f, 0xc0, 0x34, 0xc7, 0x59, 0xbe, 0xc3, 0xfe, 0x37, 0x54, 0x1c, 0xfe, 0x2c, 0x20, 0x4f, 0x89, 0x2d, 0x14, 0xbe, 0xb0, 0x88, 0xcf, 0xe0, 0x5b, 0x33, 0x6a, 0xdd, 0x09, 0x8e, 0x6c,
0x7b, 0x31, 0x06, 0xd9, 0xac, 0x9d, 0x62, 0x76, 0xc0, 0xad, 0xfd, 0x13, 0x60, 0x36, 0xc6, 0x80, 0x54, 0xa0, 0x24, 0xfe, 0xa1, 0xf1, 0x01, 0xcc, 0x72, 0x9c, 0xe5, 0x19, 0xf6, 0xbf, 0xa0, 0x62,
0x36, 0xd4, 0xa8, 0x7d, 0x29, 0x09, 0xb5, 0x59, 0xd7, 0x18, 0x6c, 0xdf, 0x56, 0xc0, 0xf6, 0xa2, 0xf3, 0xdf, 0x02, 0xb2, 0x97, 0x22, 0x90, 0xcd, 0xc6, 0x29, 0x66, 0xfb, 0xdc, 0xca, 0x3f, 0x00,
0x12, 0xb6, 0x7d, 0x01, 0x12, 0x6e, 0x6f, 0xa8, 0x71, 0xfb, 0x52, 0x12, 0x6e, 0x47, 0x27, 0xc1, 0x9a, 0x11, 0x06, 0xb4, 0x19, 0x8f, 0xda, 0x97, 0x92, 0x50, 0x9b, 0x4d, 0x8d, 0xc0, 0xf6, 0xed,
0x4d, 0xf9, 0xbe, 0x0a, 0xb8, 0x2f, 0xaa, 0x81, 0xdb, 0x17, 0x21, 0x23, 0xf7, 0x77, 0xc6, 0x20, 0x18, 0xd8, 0x5e, 0x8a, 0x85, 0x6d, 0x4f, 0x80, 0x84, 0xdb, 0x9b, 0xf1, 0xb8, 0x7d, 0x29, 0x09,
0xf7, 0x8d, 0x71, 0xc8, 0xed, 0x4b, 0x55, 0x43, 0xf7, 0xba, 0x12, 0xba, 0x97, 0x12, 0xa0, 0xdb, 0xb7, 0xc3, 0x8b, 0xe0, 0xa6, 0x7c, 0x3f, 0x0e, 0xb8, 0x2f, 0xc6, 0x03, 0xb7, 0x27, 0x42, 0x46,
0x17, 0x16, 0xc2, 0xee, 0x0d, 0x35, 0x76, 0x5f, 0x4a, 0xc2, 0xee, 0x40, 0x57, 0x21, 0xf0, 0xbe, 0xee, 0xff, 0x9f, 0x80, 0xdc, 0x37, 0x26, 0x21, 0xb7, 0x27, 0x35, 0x1e, 0xba, 0x37, 0x62, 0xa1,
0xad, 0x00, 0xef, 0x45, 0x25, 0x78, 0x07, 0x06, 0x0b, 0xd0, 0xfb, 0x7d, 0x15, 0x7a, 0x5f, 0x54, 0x7b, 0x39, 0x01, 0xba, 0x3d, 0x61, 0x01, 0xec, 0xde, 0x8c, 0xc7, 0xee, 0x4b, 0x49, 0xd8, 0xed,
0xa3, 0x77, 0xa0, 0x69, 0x09, 0xbe, 0x1f, 0xa5, 0xc1, 0xf7, 0xd5, 0x54, 0xf8, 0xf6, 0xe5, 0x29, 0xeb, 0x2a, 0x00, 0xde, 0xb7, 0x63, 0xc0, 0x7b, 0x29, 0x16, 0xbc, 0x7d, 0x83, 0xf9, 0xe8, 0xfd,
0xf0, 0xfb, 0x49, 0x2a, 0x7e, 0x5f, 0x4b, 0xc7, 0x6f, 0x5f, 0xb0, 0x0a, 0xc0, 0x37, 0xd4, 0x00, 0x7e, 0x1c, 0x7a, 0x5f, 0x8c, 0x47, 0x6f, 0x5f, 0xd3, 0x12, 0x7c, 0x3f, 0x4a, 0x83, 0xef, 0xab,
0x7e, 0x29, 0x09, 0xc0, 0x03, 0xb5, 0x87, 0x10, 0x7c, 0x33, 0x01, 0xc1, 0x97, 0x13, 0x11, 0xdc, 0xa9, 0xf0, 0xed, 0xc9, 0x8b, 0xc1, 0xef, 0x27, 0xa9, 0xf8, 0x7d, 0x2d, 0x1d, 0xbf, 0x3d, 0xc1,
0x17, 0x14, 0x81, 0xf0, 0x47, 0x69, 0x10, 0x7e, 0x35, 0x15, 0xc2, 0x03, 0x0d, 0xc6, 0x31, 0xfc, 0x71, 0x00, 0xbe, 0x19, 0x0f, 0xe0, 0x97, 0x92, 0x00, 0xdc, 0x57, 0x7b, 0x00, 0xc1, 0xb7, 0x12,
0x49, 0x2a, 0x86, 0x5f, 0x4b, 0xc7, 0xf0, 0x40, 0x83, 0x0a, 0x10, 0xff, 0xff, 0x74, 0x10, 0xbf, 0x10, 0x7c, 0x25, 0x11, 0xc1, 0x3d, 0x41, 0x21, 0x08, 0x7f, 0x94, 0x06, 0xe1, 0x57, 0x53, 0x21,
0x3e, 0x06, 0xc4, 0x7d, 0xd9, 0x4a, 0x14, 0x5f, 0x57, 0xa2, 0xf8, 0x52, 0x02, 0x8a, 0x07, 0x91, 0xdc, 0xd7, 0x60, 0x14, 0xc3, 0x9f, 0xa4, 0x62, 0xf8, 0xb5, 0x74, 0x0c, 0xf7, 0x35, 0x18, 0x03,
0x25, 0xc3, 0xf8, 0x76, 0x22, 0x8c, 0x5f, 0x49, 0x81, 0x71, 0x5f, 0x56, 0x0c, 0xc7, 0x01, 0xca, 0xe2, 0xff, 0x97, 0x0e, 0xe2, 0xd7, 0x27, 0x80, 0xb8, 0x27, 0x3b, 0x16, 0xc5, 0x37, 0x62, 0x51,
0xa2, 0x79, 0xf5, 0x9b, 0x59, 0x28, 0x6f, 0x71, 0x19, 0x68, 0x0b, 0x6a, 0x0c, 0x36, 0xf9, 0xaf, 0x7c, 0x39, 0x01, 0xc5, 0xfd, 0xc8, 0x92, 0x61, 0x7c, 0x27, 0x11, 0xc6, 0xaf, 0xa4, 0xc0, 0xb8,
0x5a, 0xe9, 0x29, 0x72, 0x6b, 0x0c, 0x16, 0xa3, 0x36, 0x54, 0xee, 0x61, 0x8f, 0xcb, 0x4a, 0xc9, 0x27, 0x2b, 0x82, 0xe3, 0x00, 0x65, 0x31, 0xbc, 0xf6, 0x4d, 0x13, 0xca, 0xdb, 0x5c, 0x06, 0xda,
0x95, 0x5b, 0x69, 0x80, 0x4c, 0x26, 0xc5, 0x74, 0x99, 0x34, 0xa9, 0xd0, 0x6e, 0xda, 0x1a, 0x83, 0x86, 0x1a, 0x83, 0x4d, 0xfe, 0x5d, 0x57, 0x7a, 0x89, 0xdc, 0x9e, 0x80, 0xc5, 0xa8, 0x03, 0x95,
0xcd, 0x68, 0x13, 0xaa, 0x44, 0xa9, 0xac, 0xcd, 0x45, 0x69, 0xe9, 0x73, 0x2b, 0x15, 0xa2, 0x11, 0x7b, 0xd8, 0xe5, 0xb2, 0x52, 0x6a, 0xe5, 0x76, 0x1a, 0x20, 0x93, 0x45, 0x31, 0x5d, 0x26, 0x2d,
0x86, 0xf9, 0x5d, 0xb1, 0x3c, 0x19, 0x4c, 0x27, 0x4b, 0xa3, 0x5b, 0x13, 0x62, 0x36, 0xfa, 0x00, 0x2a, 0x90, 0x4d, 0xdb, 0x13, 0xb0, 0x19, 0x6d, 0x41, 0x95, 0x28, 0x95, 0x8d, 0x39, 0x28, 0xad,
0xaa, 0xd4, 0x5b, 0xf9, 0x97, 0x8a, 0xa9, 0xf9, 0x74, 0x2b, 0x1d, 0xb2, 0xa9, 0x81, 0x69, 0x94, 0x7c, 0x6e, 0xa7, 0x42, 0x34, 0xc2, 0xb0, 0xb0, 0x27, 0xb6, 0x27, 0x83, 0xe9, 0x74, 0x65, 0x74,
0x72, 0x61, 0xe9, 0x89, 0x75, 0x6b, 0x0c, 0x76, 0x73, 0x03, 0x73, 0x59, 0x29, 0x19, 0x76, 0x2b, 0x7b, 0x4a, 0xcc, 0x46, 0x1f, 0x40, 0x95, 0x7a, 0x2b, 0xff, 0x5b, 0x63, 0x6a, 0x3d, 0xdd, 0x4e,
0x0d, 0xc0, 0x85, 0x45, 0x58, 0x43, 0xc8, 0x22, 0xb1, 0x5c, 0xbb, 0x95, 0x0a, 0xe5, 0xe8, 0x13, 0x87, 0x6c, 0x6a, 0x60, 0x1a, 0xa5, 0x5c, 0x58, 0x7a, 0x61, 0xdd, 0x9e, 0x80, 0xdd, 0xdc, 0xc0,
0x98, 0x95, 0x02, 0x9b, 0xcf, 0x6b, 0x82, 0x9c, 0xbb, 0x35, 0x09, 0xb0, 0xa3, 0x2e, 0x20, 0x39, 0x5c, 0x56, 0x4a, 0x85, 0xdd, 0x4e, 0x03, 0x70, 0x61, 0x11, 0x36, 0x10, 0xb0, 0x48, 0xa4, 0xd6,
0xb4, 0xb9, 0xf8, 0x49, 0x72, 0xef, 0xd6, 0x44, 0x00, 0x4f, 0xac, 0x43, 0xc7, 0x15, 0x97, 0x9e, 0x6e, 0xa7, 0x42, 0x39, 0xfa, 0x04, 0x9a, 0x52, 0x60, 0xf3, 0x75, 0x4d, 0x51, 0x73, 0xb7, 0xa7,
0xe9, 0x49, 0x78, 0x6b, 0x0c, 0xc4, 0xa3, 0x1d, 0x98, 0x66, 0xf6, 0x12, 0xf2, 0xc6, 0x64, 0xe3, 0x01, 0x76, 0xa4, 0x01, 0x92, 0x43, 0x9b, 0x8b, 0x9f, 0xa6, 0xf6, 0x6e, 0x4f, 0x05, 0xf0, 0xc4,
0xad, 0x71, 0x58, 0x4f, 0xf4, 0x1b, 0x20, 0xb2, 0x90, 0x3a, 0x41, 0x56, 0xde, 0x9a, 0x04, 0xf6, 0x3a, 0xf4, 0xbd, 0xe2, 0x86, 0x34, 0xbd, 0x08, 0x6f, 0x4f, 0x80, 0x78, 0xb4, 0x0b, 0xb3, 0xcc,
0x89, 0x7e, 0x25, 0xb5, 0x0b, 0xf1, 0x93, 0x64, 0xe7, 0xad, 0x89, 0xe0, 0x1f, 0xed, 0xc1, 0x9c, 0x5e, 0x42, 0xde, 0x84, 0x6a, 0xbc, 0x3d, 0x09, 0xeb, 0x89, 0x7e, 0x7d, 0x44, 0x16, 0x52, 0xa7,
0xac, 0x77, 0x31, 0xc2, 0x44, 0x59, 0x7a, 0x6b, 0xb2, 0x6d, 0x00, 0x7d, 0x08, 0x35, 0xf9, 0xf3, 0xa8, 0xca, 0xdb, 0xd3, 0xc0, 0x3e, 0xd1, 0xaf, 0xa4, 0x76, 0x21, 0x7e, 0x9a, 0xea, 0xbc, 0x3d,
0x6d, 0x94, 0x9a, 0xaf, 0xb7, 0xd2, 0xf7, 0x01, 0xf4, 0x31, 0xd4, 0x05, 0x68, 0x8b, 0xc9, 0x8e, 0x15, 0xfc, 0xa3, 0x7d, 0x98, 0x97, 0xf5, 0x2e, 0xde, 0x30, 0x55, 0x95, 0xde, 0x9e, 0x2e, 0x0d,
0x4d, 0xdc, 0x5b, 0xe3, 0xf7, 0x04, 0xf4, 0x0e, 0x14, 0x68, 0xc2, 0x8d, 0x16, 0xd4, 0x55, 0x95, 0xa0, 0x0f, 0xa1, 0x26, 0xff, 0xd7, 0x1b, 0xa5, 0xd6, 0xeb, 0xed, 0xf4, 0x3c, 0x80, 0x3e, 0x86,
0xd6, 0xf9, 0x84, 0xd4, 0x1d, 0x3d, 0x86, 0x06, 0x03, 0x79, 0x2e, 0xfa, 0x41, 0xcf, 0x54, 0x4c, 0xba, 0x00, 0x6d, 0xb1, 0xd8, 0x89, 0x85, 0x7b, 0x7b, 0x72, 0x4e, 0x40, 0xef, 0x40, 0x81, 0x16,
0x29, 0xf2, 0xcf, 0x96, 0x62, 0x4a, 0xb1, 0x9f, 0x96, 0xfe, 0x0f, 0x1a, 0x21, 0x67, 0x25, 0xb4, 0xdc, 0x68, 0x31, 0xbe, 0xab, 0xd2, 0x3e, 0x9f, 0x50, 0xba, 0xa3, 0xc7, 0xd0, 0x60, 0x20, 0xcf,
0x2b, 0xe9, 0xfe, 0x4a, 0x24, 0x6b, 0x63, 0x5c, 0x96, 0x88, 0xd9, 0x85, 0x19, 0xe9, 0x67, 0x0d, 0x45, 0x3f, 0xe8, 0x1b, 0x31, 0x4b, 0x0a, 0x7d, 0xe0, 0x15, 0xb3, 0xa4, 0xc8, 0x17, 0x4e, 0xff,
0xfa, 0x95, 0x7a, 0xac, 0x57, 0xf8, 0x2f, 0x91, 0xd6, 0xe5, 0x04, 0x86, 0x40, 0x68, 0x17, 0x50, 0x0b, 0x8d, 0x80, 0xb3, 0x12, 0xda, 0x95, 0x74, 0x7f, 0x25, 0x92, 0x95, 0x09, 0x2e, 0x4b, 0xc4,
0xc4, 0x34, 0x84, 0x7a, 0x75, 0x9c, 0x75, 0x88, 0xf0, 0x6b, 0x63, 0x0d, 0xc4, 0x15, 0x12, 0x72, 0xec, 0xc1, 0x9c, 0xf4, 0x65, 0x07, 0xfd, 0x4b, 0x7b, 0x64, 0x56, 0xf0, 0x93, 0x92, 0xf6, 0xe5,
0x53, 0xb5, 0x42, 0xa2, 0xbf, 0x8d, 0x28, 0x14, 0x12, 0xff, 0xef, 0xe3, 0x63, 0xa8, 0xcb, 0x3e, 0x04, 0x06, 0x5f, 0xa8, 0x06, 0x28, 0x64, 0x1a, 0x42, 0xbd, 0x3a, 0xc9, 0x3a, 0x44, 0xf8, 0xb5,
0x1a, 0xb1, 0xa1, 0xfa, 0x6f, 0x0c, 0xd9, 0x86, 0x49, 0x7f, 0x34, 0x7c, 0x02, 0xb3, 0xe1, 0x3d, 0x89, 0x06, 0xe2, 0x0a, 0x09, 0xb8, 0x69, 0xbc, 0x42, 0xc2, 0xdf, 0x98, 0xc4, 0x28, 0x24, 0xfa,
0x8c, 0x10, 0x43, 0x13, 0x52, 0xff, 0x35, 0x10, 0x86, 0x87, 0x84, 0xaf, 0xff, 0xc9, 0x3e, 0x28, 0x91, 0xc8, 0xc7, 0x50, 0x97, 0x7d, 0x34, 0x64, 0xc3, 0xf8, 0x4f, 0x37, 0x64, 0x1b, 0x26, 0x7d,
0x7d, 0xe7, 0x2f, 0x07, 0x56, 0xfc, 0xa7, 0x00, 0x39, 0xb0, 0x14, 0x3f, 0x07, 0xac, 0xe7, 0x9f, 0xfe, 0xf0, 0x09, 0x34, 0x83, 0x39, 0x8c, 0x10, 0x03, 0x0b, 0x8a, 0xff, 0xc4, 0x20, 0x08, 0x0f,
0x66, 0x87, 0x7b, 0x7b, 0x45, 0x7a, 0x3f, 0xf8, 0xf6, 0xbf, 0x03, 0x00, 0x00, 0xff, 0xff, 0xc0, 0x09, 0x9f, 0x0a, 0x90, 0x3c, 0x28, 0x7d, 0x14, 0x20, 0x07, 0x56, 0xf4, 0x0b, 0x02, 0x39, 0xb0,
0x85, 0xf8, 0x5e, 0x21, 0x3f, 0x00, 0x00, 0x62, 0xbe, 0x24, 0xd8, 0xc8, 0x3f, 0xcd, 0x8e, 0xf6, 0xf7, 0x8b, 0xf4, 0x32, 0xf1, 0xed, 0x7f,
0x05, 0x00, 0x00, 0xff, 0xff, 0x8b, 0xc6, 0x7e, 0x14, 0x4e, 0x3f, 0x00, 0x00,
} }
type DRPCMetainfoClient interface { type DRPCMetainfoClient interface {

View File

@ -432,7 +432,9 @@ message SatSegmentID {
bytes satellite_signature = 8; bytes satellite_signature = 8;
} }
message SegmentCommitResponse {} message SegmentCommitResponse {
int32 successful_pieces = 1;
}
message SegmentMakeInlineRequest { message SegmentMakeInlineRequest {
bytes stream_id = 1 [(gogoproto.customtype) = "StreamID", (gogoproto.nullable) = false]; bytes stream_id = 1 [(gogoproto.customtype) = "StreamID", (gogoproto.nullable) = false];

View File

@ -265,6 +265,7 @@ type Pointer struct {
Metadata []byte `protobuf:"bytes,8,opt,name=metadata,proto3" json:"metadata,omitempty"` Metadata []byte `protobuf:"bytes,8,opt,name=metadata,proto3" json:"metadata,omitempty"`
LastRepaired time.Time `protobuf:"bytes,9,opt,name=last_repaired,json=lastRepaired,proto3,stdtime" json:"last_repaired"` LastRepaired time.Time `protobuf:"bytes,9,opt,name=last_repaired,json=lastRepaired,proto3,stdtime" json:"last_repaired"`
RepairCount int32 `protobuf:"varint,10,opt,name=repair_count,json=repairCount,proto3" json:"repair_count,omitempty"` RepairCount int32 `protobuf:"varint,10,opt,name=repair_count,json=repairCount,proto3" json:"repair_count,omitempty"`
PieceHashesVerified bool `protobuf:"varint,11,opt,name=piece_hashes_verified,json=pieceHashesVerified,proto3" json:"piece_hashes_verified,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"` XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"` XXX_sizecache int32 `json:"-"`
@ -357,6 +358,13 @@ func (m *Pointer) GetRepairCount() int32 {
return 0 return 0
} }
func (m *Pointer) GetPieceHashesVerified() bool {
if m != nil {
return m.PieceHashesVerified
}
return false
}
// ListResponse is a response message for the List rpc call // ListResponse is a response message for the List rpc call
type ListResponse struct { type ListResponse struct {
Items []*ListResponse_Item `protobuf:"bytes,1,rep,name=items,proto3" json:"items,omitempty"` Items []*ListResponse_Item `protobuf:"bytes,1,rep,name=items,proto3" json:"items,omitempty"`
@ -472,54 +480,56 @@ func init() {
func init() { proto.RegisterFile("pointerdb.proto", fileDescriptor_75fef806d28fc810) } func init() { proto.RegisterFile("pointerdb.proto", fileDescriptor_75fef806d28fc810) }
var fileDescriptor_75fef806d28fc810 = []byte{ var fileDescriptor_75fef806d28fc810 = []byte{
// 770 bytes of a gzipped FileDescriptorProto // 801 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x53, 0xcd, 0x6e, 0xdb, 0x46, 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x54, 0xcd, 0x6e, 0xdb, 0x46,
0x10, 0x36, 0xad, 0x5f, 0x0f, 0x29, 0x5b, 0x59, 0x14, 0x2d, 0xa1, 0x14, 0x90, 0x43, 0x20, 0xad, 0x10, 0x36, 0x6d, 0xfd, 0xd0, 0x43, 0xc9, 0x56, 0xb6, 0x7f, 0x84, 0x52, 0x40, 0x0e, 0x81, 0xb4,
0x8b, 0x06, 0x74, 0xc1, 0xdc, 0x9a, 0x53, 0x5d, 0x19, 0x28, 0x01, 0x47, 0x35, 0x56, 0x46, 0x0f, 0x2e, 0x1a, 0xd0, 0x05, 0x73, 0x6b, 0x4e, 0x75, 0x65, 0xa0, 0x04, 0x1c, 0xd5, 0x58, 0x19, 0x39,
0xbd, 0x10, 0x2b, 0x71, 0x22, 0x2e, 0x2a, 0x72, 0x99, 0xdd, 0x15, 0x10, 0xfb, 0x29, 0xfa, 0x14, 0xf4, 0x42, 0xac, 0xc4, 0xb1, 0xb8, 0xa8, 0xc8, 0x65, 0x76, 0x57, 0x45, 0xec, 0xa7, 0xe8, 0x53,
0x7d, 0x8b, 0xde, 0xfb, 0x0c, 0x3d, 0x24, 0x6f, 0x52, 0x14, 0xbb, 0x4b, 0x4a, 0x4a, 0x03, 0x14, 0xf4, 0x01, 0x7a, 0xef, 0xbd, 0xcf, 0xd0, 0x43, 0xf2, 0x2a, 0xc5, 0xee, 0x92, 0x92, 0xd2, 0x00,
0xf0, 0x45, 0xda, 0x99, 0xf9, 0xe6, 0x87, 0xdf, 0x7c, 0x03, 0x67, 0xb5, 0xe0, 0x95, 0x46, 0x99, 0x05, 0x72, 0xb1, 0x77, 0x66, 0xbe, 0xf9, 0xe1, 0x37, 0xdf, 0x08, 0x4e, 0x6b, 0xc1, 0x2b, 0x8d,
0x2f, 0xe3, 0x5a, 0x0a, 0x2d, 0xc8, 0xc9, 0xce, 0x31, 0x99, 0xae, 0x85, 0x58, 0x6f, 0xf0, 0xd2, 0x32, 0x5f, 0xc4, 0xb5, 0x14, 0x5a, 0x90, 0xe3, 0xad, 0x63, 0x3c, 0x59, 0x09, 0xb1, 0x5a, 0xe3,
0x06, 0x96, 0xdb, 0x37, 0x97, 0x9a, 0x97, 0xa8, 0x34, 0x2b, 0x6b, 0x87, 0x9d, 0xc0, 0x5a, 0xac, 0x85, 0x0d, 0x2c, 0x36, 0x77, 0x17, 0x9a, 0x97, 0xa8, 0x34, 0x2b, 0x6b, 0x87, 0x1d, 0xc3, 0x4a,
0x45, 0xfb, 0xae, 0x44, 0x8e, 0xcd, 0x3b, 0x10, 0x32, 0x47, 0xa9, 0x9c, 0x15, 0xfd, 0x71, 0x0c, 0xac, 0x44, 0xfb, 0xae, 0x44, 0x8e, 0xcd, 0x7b, 0x20, 0x64, 0x8e, 0x52, 0x39, 0x2b, 0xfa, 0xe3,
0x63, 0x8a, 0xf9, 0xb6, 0xca, 0x59, 0xb5, 0xba, 0x5f, 0xac, 0x0a, 0x2c, 0x91, 0x7c, 0x0f, 0x5d, 0x10, 0x46, 0x14, 0xf3, 0x4d, 0x95, 0xb3, 0x6a, 0x79, 0x3f, 0x5f, 0x16, 0x58, 0x22, 0xf9, 0x1e,
0x7d, 0x5f, 0x63, 0xe8, 0x9d, 0x7b, 0x17, 0xa7, 0xc9, 0x57, 0xf1, 0x7e, 0x8c, 0xff, 0x42, 0x63, 0x3a, 0xfa, 0xbe, 0xc6, 0xd0, 0x3b, 0xf3, 0xce, 0x4f, 0x92, 0xaf, 0xe2, 0xdd, 0x18, 0xff, 0x85,
0xf7, 0x77, 0x77, 0x5f, 0x23, 0xb5, 0x39, 0xe4, 0x0b, 0x18, 0x94, 0xbc, 0xca, 0x24, 0xbe, 0x0d, 0xc6, 0xee, 0xdf, 0xed, 0x7d, 0x8d, 0xd4, 0xe6, 0x90, 0x2f, 0xa0, 0x5f, 0xf2, 0x2a, 0x93, 0xf8,
0x8f, 0xcf, 0xbd, 0x8b, 0x1e, 0xed, 0x97, 0xbc, 0xa2, 0xf8, 0x96, 0x7c, 0x06, 0x3d, 0x2d, 0x34, 0x3a, 0x3c, 0x3c, 0xf3, 0xce, 0xbb, 0xb4, 0x57, 0xf2, 0x8a, 0xe2, 0x6b, 0xf2, 0x29, 0x74, 0xb5,
0xdb, 0x84, 0x1d, 0xeb, 0x76, 0x06, 0xf9, 0x06, 0xc6, 0x12, 0x6b, 0xc6, 0x65, 0xa6, 0x0b, 0x89, 0xd0, 0x6c, 0x1d, 0x1e, 0x59, 0xb7, 0x33, 0xc8, 0x37, 0x30, 0x92, 0x58, 0x33, 0x2e, 0x33, 0x5d,
0xaa, 0x10, 0x9b, 0x3c, 0xec, 0x5a, 0xc0, 0x99, 0xf3, 0xdf, 0xb5, 0x6e, 0xf2, 0x2d, 0x3c, 0x51, 0x48, 0x54, 0x85, 0x58, 0xe7, 0x61, 0xc7, 0x02, 0x4e, 0x9d, 0xff, 0xb6, 0x75, 0x93, 0x6f, 0xe1,
0xdb, 0xd5, 0x0a, 0x95, 0x3a, 0xc0, 0xf6, 0x2c, 0x76, 0xdc, 0x04, 0xf6, 0xe0, 0x17, 0x40, 0x50, 0x91, 0xda, 0x2c, 0x97, 0xa8, 0xd4, 0x1e, 0xb6, 0x6b, 0xb1, 0xa3, 0x26, 0xb0, 0x03, 0x3f, 0x03,
0x32, 0xb5, 0x95, 0x98, 0xa9, 0x82, 0x99, 0x5f, 0xfe, 0x80, 0x61, 0xdf, 0xa1, 0x9b, 0xc8, 0xc2, 0x82, 0x92, 0xa9, 0x8d, 0xc4, 0x4c, 0x15, 0xcc, 0xfc, 0xe5, 0x0f, 0x18, 0xf6, 0x1c, 0xba, 0x89,
0x04, 0x16, 0xfc, 0x01, 0xa3, 0x67, 0x00, 0xfb, 0x0f, 0x21, 0x3e, 0x0c, 0xd2, 0xf9, 0x2f, 0x3f, 0xcc, 0x4d, 0x60, 0xce, 0x1f, 0x30, 0x7a, 0x02, 0xb0, 0xfb, 0x10, 0x12, 0x40, 0x3f, 0x9d, 0xbd,
0xdc, 0xa4, 0xb3, 0xf1, 0x11, 0xe9, 0xc3, 0x31, 0x5d, 0x8c, 0xbd, 0xe8, 0x01, 0x7c, 0x8a, 0xa5, 0xfa, 0xe1, 0x3a, 0x9d, 0x8e, 0x0e, 0x48, 0x0f, 0x0e, 0xe9, 0x7c, 0xe4, 0x45, 0x0f, 0x10, 0x50,
0xd0, 0x78, 0xcb, 0x71, 0x85, 0xe4, 0x29, 0x9c, 0xd4, 0xe6, 0x91, 0x55, 0xdb, 0xd2, 0xf2, 0xd4, 0x2c, 0x85, 0xc6, 0x1b, 0x8e, 0x4b, 0x24, 0x8f, 0xe1, 0xb8, 0x36, 0x8f, 0xac, 0xda, 0x94, 0x96,
0xa3, 0x43, 0xeb, 0x98, 0x6f, 0x4b, 0xf2, 0x35, 0x0c, 0x0c, 0xe1, 0x19, 0xcf, 0x2d, 0x07, 0xc1, 0xa7, 0x2e, 0xf5, 0xad, 0x63, 0xb6, 0x29, 0xc9, 0xd7, 0xd0, 0x37, 0x84, 0x67, 0x3c, 0xb7, 0x1c,
0xd5, 0xe9, 0x5f, 0xef, 0xa7, 0x47, 0x7f, 0xbf, 0x9f, 0xf6, 0xe7, 0x22, 0xc7, 0x74, 0x46, 0xfb, 0x0c, 0x2e, 0x4f, 0xfe, 0x7e, 0x3b, 0x39, 0xf8, 0xe7, 0xed, 0xa4, 0x37, 0x13, 0x39, 0xa6, 0x53,
0x26, 0x9c, 0xe6, 0xe4, 0x39, 0x74, 0x0b, 0xa6, 0x0a, 0x4b, 0x89, 0x9f, 0x3c, 0x89, 0x9b, 0xd5, 0xda, 0x33, 0xe1, 0x34, 0x27, 0x4f, 0xa1, 0x53, 0x30, 0x55, 0x58, 0x4a, 0x82, 0xe4, 0x51, 0xdc,
0xd8, 0x16, 0x3f, 0x31, 0x55, 0x50, 0x1b, 0x8e, 0x3e, 0x78, 0x30, 0x72, 0xcd, 0x17, 0xb8, 0x2e, 0xac, 0xc6, 0xb6, 0xf8, 0x89, 0xa9, 0x82, 0xda, 0x70, 0xf4, 0xce, 0x83, 0xa1, 0x6b, 0x3e, 0xc7,
0xb1, 0xd2, 0xe4, 0x15, 0x80, 0xdc, 0xad, 0xc2, 0xf6, 0xf7, 0x93, 0xa7, 0xff, 0xb3, 0x27, 0x7a, 0x55, 0x89, 0x95, 0x26, 0x2f, 0x00, 0xe4, 0x76, 0x15, 0xb6, 0x7f, 0x90, 0x3c, 0xfe, 0x9f, 0x3d,
0x00, 0x27, 0x2f, 0x61, 0x24, 0x85, 0xd0, 0x99, 0xfb, 0x80, 0xdd, 0x90, 0x67, 0xcd, 0x90, 0x03, 0xd1, 0x3d, 0x38, 0x79, 0x0e, 0x43, 0x29, 0x84, 0xce, 0xdc, 0x07, 0x6c, 0x87, 0x3c, 0x6d, 0x86,
0xdb, 0x3e, 0x9d, 0x51, 0xdf, 0xa0, 0x9c, 0x91, 0x93, 0x57, 0x30, 0x92, 0x76, 0x04, 0x97, 0xa6, 0xec, 0xdb, 0xf6, 0xe9, 0x94, 0x06, 0x06, 0xe5, 0x8c, 0x9c, 0xbc, 0x80, 0xa1, 0xb4, 0x23, 0xb8,
0xc2, 0xce, 0x79, 0xe7, 0xc2, 0x4f, 0x3e, 0xff, 0xa8, 0xe9, 0x8e, 0x1f, 0x1a, 0xc8, 0xbd, 0xa1, 0x34, 0x15, 0x1e, 0x9d, 0x1d, 0x9d, 0x07, 0xc9, 0xe7, 0xef, 0x35, 0xdd, 0xf2, 0x43, 0x07, 0x72,
0xc8, 0x14, 0xfc, 0x12, 0xe5, 0x6f, 0x1b, 0xcc, 0x4c, 0x49, 0xbb, 0xe0, 0x80, 0x82, 0x73, 0x51, 0x67, 0x28, 0x32, 0x81, 0xa0, 0x44, 0xf9, 0xeb, 0x1a, 0x33, 0x53, 0xd2, 0x2e, 0x78, 0x40, 0xc1,
0x21, 0x74, 0xf4, 0x4f, 0x07, 0x06, 0xb7, 0xae, 0x10, 0xb9, 0xfc, 0x48, 0x7d, 0x87, 0x5f, 0xd5, 0xb9, 0xa8, 0x10, 0x3a, 0xfa, 0xb3, 0x03, 0xfd, 0x1b, 0x57, 0x88, 0x5c, 0xbc, 0xa7, 0xbe, 0xfd,
0x20, 0xe2, 0x19, 0xd3, 0xec, 0x40, 0x72, 0xcf, 0xe1, 0x94, 0x57, 0x1b, 0x5e, 0x61, 0xa6, 0x1c, 0xaf, 0x6a, 0x10, 0xf1, 0x94, 0x69, 0xb6, 0x27, 0xb9, 0xa7, 0x70, 0xc2, 0xab, 0x35, 0xaf, 0x30,
0x3d, 0x96, 0xcf, 0x80, 0x8e, 0x9c, 0xb7, 0xe5, 0xec, 0x3b, 0xe8, 0xbb, 0xa1, 0x6c, 0x7f, 0x3f, 0x53, 0x8e, 0x1e, 0xcb, 0xe7, 0x80, 0x0e, 0x9d, 0xb7, 0xe5, 0xec, 0x3b, 0xe8, 0xb9, 0xa1, 0x6c,
0x09, 0x3f, 0x19, 0xbd, 0x41, 0xd2, 0x06, 0x47, 0x9e, 0x41, 0xd0, 0x54, 0x74, 0xf2, 0x31, 0x62, 0xff, 0x20, 0x09, 0x3f, 0x18, 0xbd, 0x41, 0xd2, 0x06, 0x47, 0x9e, 0xc0, 0xa0, 0xa9, 0xe8, 0xe4,
0xeb, 0x50, 0xbf, 0xf1, 0x19, 0xe5, 0x90, 0x14, 0x46, 0x2b, 0x89, 0x4c, 0x73, 0x51, 0x65, 0x39, 0x63, 0xc4, 0x76, 0x44, 0x83, 0xc6, 0x67, 0x94, 0x43, 0x52, 0x18, 0x2e, 0x25, 0x32, 0xcd, 0x45,
0xd3, 0x4e, 0x62, 0x7e, 0x32, 0x89, 0xdd, 0x79, 0xc6, 0xed, 0x79, 0xc6, 0x77, 0xed, 0x79, 0x5e, 0x95, 0xe5, 0x4c, 0x3b, 0x89, 0x05, 0xc9, 0x38, 0x76, 0xe7, 0x19, 0xb7, 0xe7, 0x19, 0xdf, 0xb6,
0x0d, 0x0d, 0xcf, 0xbf, 0x7f, 0x98, 0x7a, 0x34, 0x68, 0x53, 0x67, 0x4c, 0x23, 0x79, 0x0d, 0x67, 0xe7, 0x79, 0xe9, 0x1b, 0x9e, 0x7f, 0x7f, 0x37, 0xf1, 0xe8, 0xa0, 0x4d, 0x9d, 0x32, 0x8d, 0xe4,
0xf8, 0xae, 0xe6, 0xf2, 0xa0, 0xd8, 0xe0, 0x11, 0xc5, 0x4e, 0xf7, 0xc9, 0xb6, 0xdc, 0x04, 0x86, 0x25, 0x9c, 0xe2, 0x9b, 0x9a, 0xcb, 0xbd, 0x62, 0xfd, 0x8f, 0x28, 0x76, 0xb2, 0x4b, 0xb6, 0xe5,
0x25, 0x6a, 0x96, 0x33, 0xcd, 0xc2, 0xa1, 0xe5, 0x63, 0x67, 0x9b, 0xa9, 0x37, 0x4c, 0xe9, 0xcc, 0xc6, 0xe0, 0x97, 0xa8, 0x59, 0xce, 0x34, 0x0b, 0x7d, 0xcb, 0xc7, 0xd6, 0x36, 0x53, 0xaf, 0x99,
0x9d, 0x18, 0xe6, 0xe1, 0xc9, 0x63, 0xa6, 0x36, 0xa9, 0xb4, 0xc9, 0x34, 0x1c, 0x35, 0x07, 0xbc, 0xd2, 0x99, 0x3b, 0x31, 0xcc, 0xc3, 0xe3, 0x8f, 0x99, 0xda, 0xa4, 0xd2, 0x26, 0xd3, 0x70, 0xd4,
0x12, 0xdb, 0x4a, 0x87, 0x60, 0x6f, 0xc1, 0x77, 0xbe, 0x1f, 0x8d, 0x2b, 0x8a, 0x60, 0xd8, 0x6e, 0x1c, 0xf0, 0x52, 0x6c, 0x2a, 0x1d, 0x82, 0xbd, 0x85, 0xc0, 0xf9, 0x7e, 0x34, 0x2e, 0x92, 0xc0,
0x8c, 0x00, 0xf4, 0xd3, 0xf9, 0x4d, 0x3a, 0xbf, 0x1e, 0x1f, 0x99, 0x37, 0xbd, 0x7e, 0xfd, 0xf3, 0x67, 0x4e, 0x6a, 0x46, 0xcc, 0xa8, 0xb2, 0xdf, 0x50, 0xf2, 0x3b, 0x8e, 0x79, 0x18, 0x9c, 0x79,
0xdd, 0xf5, 0xd8, 0x8b, 0xfe, 0xf4, 0x20, 0xb8, 0xe1, 0xa6, 0xae, 0xaa, 0x45, 0xa5, 0x90, 0x24, 0xe7, 0x3e, 0xfd, 0xa4, 0x6e, 0xe5, 0x8e, 0xea, 0x55, 0x13, 0x8a, 0x22, 0xf0, 0xdb, 0x2d, 0x13,
0xd0, 0xe3, 0x1a, 0x4b, 0x15, 0x7a, 0x56, 0x67, 0x5f, 0x1e, 0x2c, 0xeb, 0x10, 0x17, 0xa7, 0x1a, 0x80, 0x5e, 0x3a, 0xbb, 0x4e, 0x67, 0x57, 0xa3, 0x03, 0xf3, 0xa6, 0x57, 0x2f, 0x7f, 0xbe, 0xbd,
0x4b, 0xea, 0xa0, 0x84, 0x40, 0xb7, 0x14, 0x12, 0xad, 0x9e, 0x87, 0xd4, 0xbe, 0x27, 0x08, 0x5d, 0x1a, 0x79, 0xd1, 0x5f, 0x1e, 0x0c, 0xae, 0xb9, 0x99, 0x45, 0xd5, 0xa2, 0x52, 0x48, 0x12, 0xe8,
0x03, 0x31, 0xb1, 0x9a, 0xe9, 0xc2, 0xaa, 0xea, 0x84, 0xda, 0x37, 0x79, 0x01, 0x83, 0xa6, 0xaa, 0x72, 0x8d, 0xa5, 0x0a, 0x3d, 0xab, 0xcd, 0x2f, 0xf7, 0x16, 0xbc, 0x8f, 0x8b, 0x53, 0x8d, 0x25,
0x4d, 0xf1, 0x13, 0xf2, 0xa9, 0xd8, 0x68, 0x0b, 0x31, 0x27, 0xcf, 0x55, 0x56, 0x4b, 0x7c, 0xc3, 0x75, 0x50, 0x42, 0xa0, 0x53, 0x0a, 0x89, 0xf6, 0x06, 0x7c, 0x6a, 0xdf, 0x63, 0x84, 0x8e, 0x81,
0xdf, 0x59, 0x85, 0x0d, 0xe9, 0x90, 0xab, 0x5b, 0x6b, 0x5f, 0x75, 0x7f, 0x3d, 0xae, 0x97, 0xcb, 0x98, 0x58, 0xcd, 0x74, 0x61, 0x95, 0x78, 0x4c, 0xed, 0x9b, 0x3c, 0x83, 0x7e, 0x53, 0xd5, 0xa6,
0xbe, 0x25, 0xee, 0xe5, 0xbf, 0x01, 0x00, 0x00, 0xff, 0xff, 0x81, 0x7b, 0x5c, 0x68, 0xb9, 0x05, 0x04, 0x09, 0xf9, 0x50, 0xa0, 0xb4, 0x85, 0x98, 0x9f, 0x09, 0xae, 0xb2, 0x5a, 0xe2, 0x1d, 0x7f,
0x00, 0x00, 0x63, 0x55, 0xe9, 0x53, 0x9f, 0xab, 0x1b, 0x6b, 0x5f, 0x76, 0x7e, 0x39, 0xac, 0x17, 0x8b, 0x9e,
0x25, 0xfb, 0xf9, 0xbf, 0x01, 0x00, 0x00, 0xff, 0xff, 0xd1, 0xa5, 0x77, 0x55, 0xed, 0x05, 0x00,
0x00,
} }

View File

@ -59,6 +59,7 @@ message Pointer {
google.protobuf.Timestamp last_repaired = 9 [(gogoproto.stdtime) = true, (gogoproto.nullable) = false]; google.protobuf.Timestamp last_repaired = 9 [(gogoproto.stdtime) = true, (gogoproto.nullable) = false];
int32 repair_count = 10; int32 repair_count = 10;
bool piece_hashes_verified = 11;
} }
// ListResponse is a response message for the List rpc call // ListResponse is a response message for the List rpc call

View File

@ -3168,7 +3168,14 @@
] ]
}, },
{ {
"name": "SegmentCommitResponse" "name": "SegmentCommitResponse",
"fields": [
{
"id": 1,
"name": "successful_pieces",
"type": "int32"
}
]
}, },
{ {
"name": "SegmentMakeInlineRequest", "name": "SegmentMakeInlineRequest",
@ -5550,6 +5557,11 @@
"id": 10, "id": 10,
"name": "repair_count", "name": "repair_count",
"type": "int32" "type": "int32"
},
{
"id": 11,
"name": "piece_hashes_verified",
"type": "bool"
} }
] ]
}, },

View File

@ -19,6 +19,7 @@ import (
monkit "gopkg.in/spacemonkeygo/monkit.v2" monkit "gopkg.in/spacemonkeygo/monkit.v2"
"storj.io/storj/pkg/auth" "storj.io/storj/pkg/auth"
"storj.io/storj/pkg/identity"
"storj.io/storj/pkg/macaroon" "storj.io/storj/pkg/macaroon"
"storj.io/storj/pkg/pb" "storj.io/storj/pkg/pb"
"storj.io/storj/pkg/signing" "storj.io/storj/pkg/signing"
@ -76,6 +77,7 @@ type Endpoint struct {
orders *orders.Service orders *orders.Service
overlay *overlay.Service overlay *overlay.Service
partnerinfo attribution.DB partnerinfo attribution.DB
peerIdentities overlay.PeerIdentities
projectUsage *accounting.ProjectUsage projectUsage *accounting.ProjectUsage
containment Containment containment Containment
apiKeys APIKeys apiKeys APIKeys
@ -85,7 +87,7 @@ type Endpoint struct {
} }
// NewEndpoint creates new metainfo endpoint instance // NewEndpoint creates new metainfo endpoint instance
func NewEndpoint(log *zap.Logger, metainfo *Service, orders *orders.Service, cache *overlay.Service, partnerinfo attribution.DB, func NewEndpoint(log *zap.Logger, metainfo *Service, orders *orders.Service, cache *overlay.Service, partnerinfo attribution.DB, peerIdentities overlay.PeerIdentities,
containment Containment, apiKeys APIKeys, projectUsage *accounting.ProjectUsage, rsConfig RSConfig, satellite signing.Signer) *Endpoint { containment Containment, apiKeys APIKeys, projectUsage *accounting.ProjectUsage, rsConfig RSConfig, satellite signing.Signer) *Endpoint {
// TODO do something with too many params // TODO do something with too many params
return &Endpoint{ return &Endpoint{
@ -94,6 +96,7 @@ func NewEndpoint(log *zap.Logger, metainfo *Service, orders *orders.Service, cac
orders: orders, orders: orders,
overlay: cache, overlay: cache,
partnerinfo: partnerinfo, partnerinfo: partnerinfo,
peerIdentities: peerIdentities,
containment: containment, containment: containment,
apiKeys: apiKeys, apiKeys: apiKeys,
projectUsage: projectUsage, projectUsage: projectUsage,
@ -270,6 +273,7 @@ func (endpoint *Endpoint) CommitSegmentOld(ctx context.Context, req *pb.SegmentC
for _, piece := range req.GetPointer().GetRemote().GetRemotePieces() { for _, piece := range req.GetPointer().GetRemote().GetRemotePieces() {
piece.Hash = nil piece.Hash = nil
} }
req.Pointer.PieceHashesVerified = true
inlineUsed, remoteUsed := calculateSpaceUsed(req.Pointer) inlineUsed, remoteUsed := calculateSpaceUsed(req.Pointer)
@ -475,18 +479,30 @@ func (endpoint *Endpoint) filterValidPieces(ctx context.Context, pointer *pb.Poi
defer mon.Task()(&ctx)(&err) defer mon.Task()(&ctx)(&err)
if pointer.Type == pb.Pointer_REMOTE { if pointer.Type == pb.Pointer_REMOTE {
var remotePieces []*pb.RemotePiece
remote := pointer.Remote remote := pointer.Remote
peerIDMap, err := endpoint.mapNodesFor(ctx, remote.RemotePieces)
if err != nil {
return err
}
var remotePieces []*pb.RemotePiece
allSizesValid := true allSizesValid := true
lastPieceSize := int64(0) lastPieceSize := int64(0)
for _, piece := range remote.RemotePieces { for _, piece := range remote.RemotePieces {
// TODO enable piece hash signature verification // Verify storagenode signature on piecehash
peerID, ok := peerIDMap[piece.NodeId]
if !ok {
endpoint.log.Warn("Identity chain unknown for node", zap.String("nodeID", piece.NodeId.String()))
continue
}
signee := signing.SigneeFromPeerIdentity(peerID)
err = endpoint.validatePieceHash(ctx, piece, limits) err = endpoint.validatePieceHash(ctx, piece, limits, signee)
if err != nil { if err != nil {
// TODO maybe this should be logged also to uplink too // TODO maybe this should be logged also to uplink too
endpoint.log.Sugar().Warn(err) endpoint.log.Warn("Problem validating piece hash", zap.Error(err))
continue continue
} }
@ -534,6 +550,23 @@ func (endpoint *Endpoint) filterValidPieces(ctx context.Context, pointer *pb.Poi
return nil return nil
} }
func (endpoint *Endpoint) mapNodesFor(ctx context.Context, pieces []*pb.RemotePiece) (map[storj.NodeID]*identity.PeerIdentity, error) {
nodeIDList := storj.NodeIDList{}
for _, piece := range pieces {
nodeIDList = append(nodeIDList, piece.NodeId)
}
peerIDList, err := endpoint.peerIdentities.BatchGet(ctx, nodeIDList)
if err != nil {
return nil, Error.Wrap(err)
}
peerIDMap := make(map[storj.NodeID]*identity.PeerIdentity, len(peerIDList))
for _, peerID := range peerIDList {
peerIDMap[peerID.ID] = peerID
}
return peerIDMap, nil
}
// CreatePath will create a Segment path // CreatePath will create a Segment path
func CreatePath(ctx context.Context, projectID uuid.UUID, segmentIndex int64, bucket, path []byte) (_ storj.Path, err error) { func CreatePath(ctx context.Context, projectID uuid.UUID, segmentIndex int64, bucket, path []byte) (_ storj.Path, err error) {
defer mon.Task()(&ctx)(&err) defer mon.Task()(&ctx)(&err)
@ -1393,6 +1426,8 @@ func (endpoint *Endpoint) CommitSegment(ctx context.Context, req *pb.SegmentComm
CreationDate: streamID.CreationDate, CreationDate: streamID.CreationDate,
ExpirationDate: streamID.ExpirationDate, ExpirationDate: streamID.ExpirationDate,
Metadata: metadata, Metadata: metadata,
PieceHashesVerified: true,
} }
orderLimits := make([]*pb.OrderLimit, len(segmentID.OriginalOrderLimits)) orderLimits := make([]*pb.OrderLimit, len(segmentID.OriginalOrderLimits))
@ -1454,7 +1489,9 @@ func (endpoint *Endpoint) CommitSegment(ctx context.Context, req *pb.SegmentComm
return nil, status.Error(codes.Internal, err.Error()) return nil, status.Error(codes.Internal, err.Error())
} }
return &pb.SegmentCommitResponse{}, nil return &pb.SegmentCommitResponse{
SuccessfulPieces: int32(len(pointer.Remote.RemotePieces)),
}, nil
} }
// MakeInlineSegment makes inline segment on satellite // MakeInlineSegment makes inline segment on satellite

View File

@ -20,8 +20,10 @@ import (
"storj.io/storj/internal/memory" "storj.io/storj/internal/memory"
"storj.io/storj/internal/testcontext" "storj.io/storj/internal/testcontext"
"storj.io/storj/internal/testidentity"
"storj.io/storj/internal/testplanet" "storj.io/storj/internal/testplanet"
"storj.io/storj/internal/testrand" "storj.io/storj/internal/testrand"
"storj.io/storj/pkg/identity"
"storj.io/storj/pkg/macaroon" "storj.io/storj/pkg/macaroon"
"storj.io/storj/pkg/pb" "storj.io/storj/pkg/pb"
"storj.io/storj/pkg/signing" "storj.io/storj/pkg/signing"
@ -281,6 +283,11 @@ func TestCommitSegment(t *testing.T) {
require.NoError(t, err) require.NoError(t, err)
defer ctx.Check(metainfo.Close) defer ctx.Check(metainfo.Close)
fullIDMap := make(map[storj.NodeID]*identity.FullIdentity)
for _, node := range planet.StorageNodes {
fullIDMap[node.ID()] = node.Identity
}
{ {
// error if pointer is nil // error if pointer is nil
_, err = metainfo.CommitSegment(ctx, "bucket", "path", -1, nil, []*pb.OrderLimit{}) _, err = metainfo.CommitSegment(ctx, "bucket", "path", -1, nil, []*pb.OrderLimit{})
@ -303,7 +310,7 @@ func TestCommitSegment(t *testing.T) {
usedForPieces := addressedLimits[:redundancy.RepairThreshold-1] usedForPieces := addressedLimits[:redundancy.RepairThreshold-1]
pieces := make([]*pb.RemotePiece, len(usedForPieces)) pieces := make([]*pb.RemotePiece, len(usedForPieces))
for i, limit := range usedForPieces { for i, limit := range usedForPieces {
pieces[i] = &pb.RemotePiece{ newPiece := &pb.RemotePiece{
PieceNum: int32(i), PieceNum: int32(i),
NodeId: limit.Limit.StorageNodeId, NodeId: limit.Limit.StorageNodeId,
Hash: &pb.PieceHash{ Hash: &pb.PieceHash{
@ -312,6 +319,16 @@ func TestCommitSegment(t *testing.T) {
Timestamp: time.Now(), Timestamp: time.Now(),
}, },
} }
fullID := fullIDMap[limit.Limit.StorageNodeId]
require.NotNil(t, fullID)
signer := signing.SignerFromFullIdentity(fullID)
newHash, err := signing.SignPieceHash(ctx, signer, newPiece.Hash)
require.NoError(t, err)
newPiece.Hash = newHash
pieces[i] = newPiece
} }
pointer := &pb.Pointer{ pointer := &pb.Pointer{
@ -352,7 +369,7 @@ func TestCommitSegment(t *testing.T) {
usedForPieces := addressedLimits[:redundancy.SuccessThreshold-1] usedForPieces := addressedLimits[:redundancy.SuccessThreshold-1]
pieces := make([]*pb.RemotePiece, len(usedForPieces)) pieces := make([]*pb.RemotePiece, len(usedForPieces))
for i, limit := range usedForPieces { for i, limit := range usedForPieces {
pieces[i] = &pb.RemotePiece{ newPiece := &pb.RemotePiece{
PieceNum: int32(i), PieceNum: int32(i),
NodeId: limit.Limit.StorageNodeId, NodeId: limit.Limit.StorageNodeId,
Hash: &pb.PieceHash{ Hash: &pb.PieceHash{
@ -361,6 +378,16 @@ func TestCommitSegment(t *testing.T) {
Timestamp: time.Now(), Timestamp: time.Now(),
}, },
} }
fullID := fullIDMap[limit.Limit.StorageNodeId]
require.NotNil(t, fullID)
signer := signing.SignerFromFullIdentity(fullID)
newHash, err := signing.SignPieceHash(ctx, signer, newPiece.Hash)
require.NoError(t, err)
newPiece.Hash = newHash
pieces[i] = newPiece
} }
pointer := &pb.Pointer{ pointer := &pb.Pointer{
@ -546,10 +573,16 @@ func TestDoubleCommitSegment(t *testing.T) {
require.NoError(t, err) require.NoError(t, err)
defer ctx.Check(metainfo.Close) defer ctx.Check(metainfo.Close)
pointer, limits := runCreateSegment(ctx, t, metainfo) fullIDMap := make(map[storj.NodeID]*identity.FullIdentity)
for _, node := range planet.StorageNodes {
fullIDMap[node.ID()] = node.Identity
}
_, err = metainfo.CommitSegment(ctx, "my-bucket-name", "file/path", -1, pointer, limits) pointer, limits := runCreateSegment(ctx, t, metainfo, fullIDMap)
savedPointer, err := metainfo.CommitSegment(ctx, "my-bucket-name", "file/path", -1, pointer, limits)
require.NoError(t, err) require.NoError(t, err)
require.True(t, savedPointer.PieceHashesVerified)
_, err = metainfo.CommitSegment(ctx, "my-bucket-name", "file/path", -1, pointer, limits) _, err = metainfo.CommitSegment(ctx, "my-bucket-name", "file/path", -1, pointer, limits)
require.Error(t, err) require.Error(t, err)
@ -561,91 +594,124 @@ func TestCommitSegmentPointer(t *testing.T) {
// all tests needs to generate error // all tests needs to generate error
tests := []struct { tests := []struct {
// defines how modify pointer before CommitSegment // defines how modify pointer before CommitSegment
Modify func(pointer *pb.Pointer) Modify func(pointer *pb.Pointer, fullIDMap map[storj.NodeID]*identity.FullIdentity)
ErrorMessage string ErrorMessage string
}{ }{
{ {
Modify: func(pointer *pb.Pointer) { Modify: func(pointer *pb.Pointer, _ map[storj.NodeID]*identity.FullIdentity) {
pointer.ExpirationDate = pointer.ExpirationDate.Add(time.Second * 100) pointer.ExpirationDate = pointer.ExpirationDate.Add(time.Second * 100)
}, },
ErrorMessage: "pointer expiration date does not match requested one", ErrorMessage: "pointer expiration date does not match requested one",
}, },
{ {
Modify: func(pointer *pb.Pointer) { Modify: func(pointer *pb.Pointer, _ map[storj.NodeID]*identity.FullIdentity) {
pointer.Remote.Redundancy.MinReq += 100 pointer.Remote.Redundancy.MinReq += 100
}, },
ErrorMessage: "pointer redundancy scheme date does not match requested one", ErrorMessage: "pointer redundancy scheme date does not match requested one",
}, },
{ {
Modify: func(pointer *pb.Pointer) { Modify: func(pointer *pb.Pointer, _ map[storj.NodeID]*identity.FullIdentity) {
pointer.Remote.Redundancy.RepairThreshold += 100 pointer.Remote.Redundancy.RepairThreshold += 100
}, },
ErrorMessage: "pointer redundancy scheme date does not match requested one", ErrorMessage: "pointer redundancy scheme date does not match requested one",
}, },
{ {
Modify: func(pointer *pb.Pointer) { Modify: func(pointer *pb.Pointer, _ map[storj.NodeID]*identity.FullIdentity) {
pointer.Remote.Redundancy.SuccessThreshold += 100 pointer.Remote.Redundancy.SuccessThreshold += 100
}, },
ErrorMessage: "pointer redundancy scheme date does not match requested one", ErrorMessage: "pointer redundancy scheme date does not match requested one",
}, },
{ {
Modify: func(pointer *pb.Pointer) { Modify: func(pointer *pb.Pointer, _ map[storj.NodeID]*identity.FullIdentity) {
pointer.Remote.Redundancy.Total += 100 pointer.Remote.Redundancy.Total += 100
}, },
// this error is triggered earlier then Create/Commit RS comparison // this error is triggered earlier then Create/Commit RS comparison
ErrorMessage: "invalid no order limit for piece", ErrorMessage: "invalid no order limit for piece",
}, },
{ {
Modify: func(pointer *pb.Pointer) { Modify: func(pointer *pb.Pointer, _ map[storj.NodeID]*identity.FullIdentity) {
pointer.Remote.Redundancy.ErasureShareSize += 100 pointer.Remote.Redundancy.ErasureShareSize += 100
}, },
ErrorMessage: "pointer redundancy scheme date does not match requested one", ErrorMessage: "pointer redundancy scheme date does not match requested one",
}, },
{ {
Modify: func(pointer *pb.Pointer) { Modify: func(pointer *pb.Pointer, _ map[storj.NodeID]*identity.FullIdentity) {
pointer.Remote.Redundancy.Type = 100 pointer.Remote.Redundancy.Type = 100
}, },
ErrorMessage: "pointer redundancy scheme date does not match requested one", ErrorMessage: "pointer redundancy scheme date does not match requested one",
}, },
{ {
Modify: func(pointer *pb.Pointer) { Modify: func(pointer *pb.Pointer, _ map[storj.NodeID]*identity.FullIdentity) {
pointer.Type = pb.Pointer_INLINE pointer.Type = pb.Pointer_INLINE
}, },
ErrorMessage: "pointer type is INLINE but remote segment is set", ErrorMessage: "pointer type is INLINE but remote segment is set",
}, },
{ {
// no piece hash removes piece from pointer, not enough pieces for successful upload // no piece hash removes piece from pointer, not enough pieces for successful upload
Modify: func(pointer *pb.Pointer) { Modify: func(pointer *pb.Pointer, _ map[storj.NodeID]*identity.FullIdentity) {
pointer.Remote.RemotePieces[0].Hash = nil pointer.Remote.RemotePieces[0].Hash = nil
}, },
ErrorMessage: "Number of valid pieces (2) is less than the success threshold (3)", ErrorMessage: "Number of valid pieces (2) is less than the success threshold (3)",
}, },
{ {
// invalid timestamp removes piece from pointer, not enough pieces for successful upload // invalid timestamp removes piece from pointer, not enough pieces for successful upload
Modify: func(pointer *pb.Pointer) { Modify: func(pointer *pb.Pointer, _ map[storj.NodeID]*identity.FullIdentity) {
pointer.Remote.RemotePieces[0].Hash.Timestamp = time.Now().Add(-24 * time.Hour) pointer.Remote.RemotePieces[0].Hash.Timestamp = time.Now().Add(-24 * time.Hour)
}, },
ErrorMessage: "Number of valid pieces (2) is less than the success threshold (3)", ErrorMessage: "Number of valid pieces (2) is less than the success threshold (3)",
}, },
{ {
// invalid hash PieceID removes piece from pointer, not enough pieces for successful upload // invalid hash PieceID removes piece from pointer, not enough pieces for successful upload
Modify: func(pointer *pb.Pointer) { Modify: func(pointer *pb.Pointer, _ map[storj.NodeID]*identity.FullIdentity) {
pointer.Remote.RemotePieces[0].Hash.PieceId = storj.PieceID{1} pointer.Remote.RemotePieces[0].Hash.PieceId = storj.PieceID{1}
}, },
ErrorMessage: "Number of valid pieces (2) is less than the success threshold (3)", ErrorMessage: "Number of valid pieces (2) is less than the success threshold (3)",
}, },
{ {
Modify: func(pointer *pb.Pointer) { Modify: func(pointer *pb.Pointer, fullIDMap map[storj.NodeID]*identity.FullIdentity) {
pointer.Remote.RemotePieces[0].Hash.PieceSize = 1 pointer.Remote.RemotePieces[0].Hash.PieceSize = 1
ctx := testcontext.New(t)
snFullID := fullIDMap[pointer.Remote.RemotePieces[0].NodeId]
require.NotNil(t, snFullID)
signer := signing.SignerFromFullIdentity(snFullID)
storageNodeHash, err := signing.SignPieceHash(ctx, signer, pointer.Remote.RemotePieces[0].Hash)
require.NoError(t, err)
pointer.Remote.RemotePieces[0].Hash = storageNodeHash
}, },
ErrorMessage: "all pieces needs to have the same size", ErrorMessage: "all pieces needs to have the same size",
}, },
{ {
Modify: func(pointer *pb.Pointer) { Modify: func(pointer *pb.Pointer, _ map[storj.NodeID]*identity.FullIdentity) {
pointer.SegmentSize = 100 pointer.SegmentSize = 100
}, },
ErrorMessage: "expected piece size is different from provided", ErrorMessage: "expected piece size is different from provided",
}, },
{
Modify: func(pointer *pb.Pointer, _ map[storj.NodeID]*identity.FullIdentity) {
// nil piece hash signature removes piece from pointer, not enough pieces for successful upload
pointer.Remote.RemotePieces[0].Hash.Signature = nil
},
ErrorMessage: "Number of valid pieces (2) is less than the success threshold (3)",
},
{
Modify: func(pointer *pb.Pointer, _ map[storj.NodeID]*identity.FullIdentity) {
// invalid piece hash signature removes piece from pointer, not enough pieces for successful upload
pointer.Remote.RemotePieces[0].Hash.Signature = nil
ctx := testcontext.New(t)
ca, err := testidentity.NewTestCA(ctx)
require.NoError(t, err)
badFullID, err := ca.NewIdentity()
require.NoError(t, err)
signer := signing.SignerFromFullIdentity(badFullID)
newHash, err := signing.SignPieceHash(ctx, signer, pointer.Remote.RemotePieces[0].Hash)
require.NoError(t, err)
pointer.Remote.RemotePieces[0].Hash = newHash
},
ErrorMessage: "Number of valid pieces (2) is less than the success threshold (3)",
},
} }
testplanet.Run(t, testplanet.Config{ testplanet.Run(t, testplanet.Config{
@ -657,9 +723,14 @@ func TestCommitSegmentPointer(t *testing.T) {
require.NoError(t, err) require.NoError(t, err)
defer ctx.Check(metainfo.Close) defer ctx.Check(metainfo.Close)
fullIDMap := make(map[storj.NodeID]*identity.FullIdentity)
for _, node := range planet.StorageNodes {
fullIDMap[node.ID()] = node.Identity
}
for i, test := range tests { for i, test := range tests {
pointer, limits := runCreateSegment(ctx, t, metainfo) pointer, limits := runCreateSegment(ctx, t, metainfo, fullIDMap)
test.Modify(pointer) test.Modify(pointer, fullIDMap)
_, err = metainfo.CommitSegment(ctx, "my-bucket-name", "file/path", -1, pointer, limits) _, err = metainfo.CommitSegment(ctx, "my-bucket-name", "file/path", -1, pointer, limits)
require.Error(t, err, "Case #%v", i) require.Error(t, err, "Case #%v", i)
@ -751,7 +822,7 @@ func TestGetProjectInfo(t *testing.T) {
}) })
} }
func runCreateSegment(ctx context.Context, t *testing.T, metainfo *metainfo.Client) (*pb.Pointer, []*pb.OrderLimit) { func runCreateSegment(ctx context.Context, t *testing.T, metainfo *metainfo.Client, fullIDMap map[storj.NodeID]*identity.FullIdentity) (*pb.Pointer, []*pb.OrderLimit) {
pointer := createTestPointer(t) pointer := createTestPointer(t)
addressedLimits, rootPieceID, _, err := metainfo.CreateSegment(ctx, "my-bucket-name", "file/path", -1, pointer.Remote.Redundancy, memory.MiB.Int64(), pointer.ExpirationDate) addressedLimits, rootPieceID, _, err := metainfo.CreateSegment(ctx, "my-bucket-name", "file/path", -1, pointer.Remote.Redundancy, memory.MiB.Int64(), pointer.ExpirationDate)
@ -764,8 +835,16 @@ func runCreateSegment(ctx context.Context, t *testing.T, metainfo *metainfo.Clie
limits[i] = addressedLimit.Limit limits[i] = addressedLimit.Limit
if len(pointer.Remote.RemotePieces) > i { if len(pointer.Remote.RemotePieces) > i {
pointer.Remote.RemotePieces[i].NodeId = addressedLimits[i].Limit.StorageNodeId nodeID := addressedLimits[i].Limit.StorageNodeId
pointer.Remote.RemotePieces[i].NodeId = nodeID
pointer.Remote.RemotePieces[i].Hash.PieceId = addressedLimits[i].Limit.PieceId pointer.Remote.RemotePieces[i].Hash.PieceId = addressedLimits[i].Limit.PieceId
snFullID := fullIDMap[nodeID]
require.NotNil(t, snFullID)
signer := signing.SignerFromFullIdentity(snFullID)
storageNodeHash, err := signing.SignPieceHash(ctx, signer, pointer.Remote.RemotePieces[i].Hash)
require.NoError(t, err)
pointer.Remote.RemotePieces[i].Hash = storageNodeHash
} }
} }
@ -970,16 +1049,29 @@ func TestBeginCommitListSegment(t *testing.T) {
}) })
require.NoError(t, err) require.NoError(t, err)
fullIDMap := make(map[storj.NodeID]*identity.FullIdentity)
for _, node := range planet.StorageNodes {
fullIDMap[node.ID()] = node.Identity
}
makeResult := func(num int32) *pb.SegmentPieceUploadResult { makeResult := func(num int32) *pb.SegmentPieceUploadResult {
nodeID := limits[num].Limit.StorageNodeId
hash := &pb.PieceHash{
PieceId: limits[num].Limit.PieceId,
PieceSize: 1048832,
Timestamp: time.Now(),
}
fullID := fullIDMap[nodeID]
require.NotNil(t, fullID)
signer := signing.SignerFromFullIdentity(fullID)
signedHash, err := signing.SignPieceHash(ctx, signer, hash)
require.NoError(t, err)
return &pb.SegmentPieceUploadResult{ return &pb.SegmentPieceUploadResult{
PieceNum: num, PieceNum: num,
NodeId: limits[num].Limit.StorageNodeId, NodeId: nodeID,
Hash: &pb.PieceHash{ Hash: signedHash,
PieceId: limits[num].Limit.PieceId,
PieceSize: 1048832,
Timestamp: time.Now(),
// TODO we still not verifying signature in metainfo
},
} }
} }
err = metainfoClient.CommitSegmentNew(ctx, metainfo.CommitSegmentParams{ err = metainfoClient.CommitSegmentNew(ctx, metainfo.CommitSegmentParams{

View File

@ -20,6 +20,7 @@ import (
"storj.io/storj/pkg/encryption" "storj.io/storj/pkg/encryption"
"storj.io/storj/pkg/macaroon" "storj.io/storj/pkg/macaroon"
"storj.io/storj/pkg/pb" "storj.io/storj/pkg/pb"
"storj.io/storj/pkg/signing"
"storj.io/storj/pkg/storj" "storj.io/storj/pkg/storj"
"storj.io/storj/satellite/console" "storj.io/storj/satellite/console"
) )
@ -348,13 +349,18 @@ func (endpoint *Endpoint) validateRedundancy(ctx context.Context, redundancy *pb
return nil return nil
} }
func (endpoint *Endpoint) validatePieceHash(ctx context.Context, piece *pb.RemotePiece, limits []*pb.OrderLimit) (err error) { func (endpoint *Endpoint) validatePieceHash(ctx context.Context, piece *pb.RemotePiece, limits []*pb.OrderLimit, signee signing.Signee) (err error) {
defer mon.Task()(&ctx)(&err) defer mon.Task()(&ctx)(&err)
if piece.Hash == nil { if piece.Hash == nil {
return errs.New("no piece hash, removing from pointer %v (%v)", piece.NodeId, piece.PieceNum) return errs.New("no piece hash, removing from pointer %v (%v)", piece.NodeId, piece.PieceNum)
} }
err = signing.VerifyPieceHashSignature(ctx, signee, piece.Hash)
if err != nil {
return errs.New("piece hash signature could not be verified for node %v: %v", piece.NodeId, err)
}
timestamp := piece.Hash.Timestamp timestamp := piece.Hash.Timestamp
if timestamp.Before(time.Now().Add(-pieceHashExpiration)) { if timestamp.Before(time.Now().Add(-pieceHashExpiration)) {
return errs.New("piece hash timestamp is too old (%v), removing from pointer %v (num: %v)", timestamp, piece.NodeId, piece.PieceNum) return errs.New("piece hash timestamp is too old (%v), removing from pointer %v (num: %v)", timestamp, piece.NodeId, piece.PieceNum)

View File

@ -61,25 +61,34 @@ func TestPeerIdentities(t *testing.T) {
} }
} }
{ // get multiple { // get multiple with invalid
list := make(map[storj.NodeID]*identity.PeerIdentity) list := make(map[storj.NodeID]*identity.PeerIdentity)
var ids []storj.NodeID ids := storj.NodeIDList{}
savedIDs := make(map[storj.NodeID]bool)
unsavedIDs := make(map[storj.NodeID]bool)
for i := 0; i < 10; i++ { for i := 0; i < 10; i++ {
ident := testidentity.MustPregeneratedSignedIdentity(i, storj.LatestIDVersion()) ident := testidentity.MustPregeneratedSignedIdentity(i, storj.LatestIDVersion())
list[ident.ID] = ident.PeerIdentity() list[ident.ID] = ident.PeerIdentity()
ids = append(ids, ident.ID)
// only place half in the table
if i%2 == 0 {
unsavedIDs[ident.ID] = true
continue
}
err := idents.Set(ctx, ident.ID, ident.PeerIdentity()) err := idents.Set(ctx, ident.ID, ident.PeerIdentity())
require.NoError(t, err) require.NoError(t, err)
savedIDs[ident.ID] = true
ids = append(ids, ident.ID)
} }
got, err := idents.BatchGet(ctx, ids) got, err := idents.BatchGet(ctx, ids)
require.NoError(t, err) require.NoError(t, err)
require.Len(t, got, len(ids)) require.Len(t, got, len(savedIDs))
for _, gotIdent := range got { for _, gotIdent := range got {
require.Equal(t, encode(list[gotIdent.ID]), encode(gotIdent)) require.Equal(t, encode(list[gotIdent.ID]), encode(gotIdent))
require.True(t, savedIDs[gotIdent.ID])
require.False(t, unsavedIDs[gotIdent.ID])
} }
} }
}) })

View File

@ -452,6 +452,7 @@ func New(log *zap.Logger, full *identity.FullIdentity, db DB, revocationDB exten
peer.Orders.Service, peer.Orders.Service,
peer.Overlay.Service, peer.Overlay.Service,
peer.DB.Attribution(), peer.DB.Attribution(),
peer.DB.PeerIdentities(),
peer.DB.Containment(), peer.DB.Containment(),
peer.DB.Console().APIKeys(), peer.DB.Console().APIKeys(),
peer.Accounting.ProjectUsage, peer.Accounting.ProjectUsage,