From 4ab1d6dde8adb2cf3db655d013efbc8901c8af32 Mon Sep 17 00:00:00 2001 From: 0xluk Date: Mon, 11 Mar 2024 18:38:39 +0200 Subject: [PATCH] added transfer transactions in storage --- processor/processor.go | 2 +- protobuff/archive.pb.go | 864 ++++++++++++++++++++++------- protobuff/archive.pb.gw.go | 170 ++++++ protobuff/archive.proto | 28 + protobuff/archive_grpc.pb.go | 92 ++- rpc/rpc_server.go | 22 + store/keys.go | 30 +- store/store.go | 84 ++- store/store_test.go | 273 ++++++--- utils/utils.go | 2 + validator/computors/validator.go | 4 +- validator/quorum/validator.go | 8 +- validator/quorum/validator_test.go | 6 +- validator/tick/validator.go | 4 +- validator/tx/validator.go | 89 ++- validator/tx/validator_test.go | 232 ++++++++ validator/validator.go | 11 +- 17 files changed, 1596 insertions(+), 325 deletions(-) create mode 100644 validator/tx/validator_test.go diff --git a/processor/processor.go b/processor/processor.go index 889a177..3cfa5a8 100644 --- a/processor/processor.go +++ b/processor/processor.go @@ -128,7 +128,7 @@ func (p *Processor) getLastProcessedTick(ctx context.Context, currentTickInfo ty lastTick, err := p.ps.GetLastProcessedTick(ctx) if err != nil { //handles first run of the archiver where there is nothing in storage - // in this case we start from the initial tick of the current epoch + // in this case we last tick is the initial tick of the current epoch - 1 if errors.Is(err, store.ErrNotFound) { return uint64(currentTickInfo.InitialTick - 1), nil } diff --git a/protobuff/archive.pb.go b/protobuff/archive.pb.go index f2fb5c9..7e233cd 100644 --- a/protobuff/archive.pb.go +++ b/protobuff/archive.pb.go @@ -1296,6 +1296,108 @@ func (x *IdentityInfo) GetSiblingsHex() []string { return nil } +type TransferTransactionsPerTick struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + TickNumber uint32 `protobuf:"varint,1,opt,name=tick_number,json=tickNumber,proto3" json:"tick_number,omitempty"` + Transactions *Transactions `protobuf:"bytes,2,opt,name=transactions,proto3" json:"transactions,omitempty"` +} + +func (x *TransferTransactionsPerTick) Reset() { + *x = TransferTransactionsPerTick{} + if protoimpl.UnsafeEnabled { + mi := &file_archive_proto_msgTypes[20] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *TransferTransactionsPerTick) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*TransferTransactionsPerTick) ProtoMessage() {} + +func (x *TransferTransactionsPerTick) ProtoReflect() protoreflect.Message { + mi := &file_archive_proto_msgTypes[20] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use TransferTransactionsPerTick.ProtoReflect.Descriptor instead. +func (*TransferTransactionsPerTick) Descriptor() ([]byte, []int) { + return file_archive_proto_rawDescGZIP(), []int{20} +} + +func (x *TransferTransactionsPerTick) GetTickNumber() uint32 { + if x != nil { + return x.TickNumber + } + return 0 +} + +func (x *TransferTransactionsPerTick) GetTransactions() *Transactions { + if x != nil { + return x.Transactions + } + return nil +} + +type TransferTransactions struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + TransferTransactionsPerTick []*TransferTransactionsPerTick `protobuf:"bytes,1,rep,name=transfer_transactions_per_tick,json=transferTransactionsPerTick,proto3" json:"transfer_transactions_per_tick,omitempty"` +} + +func (x *TransferTransactions) Reset() { + *x = TransferTransactions{} + if protoimpl.UnsafeEnabled { + mi := &file_archive_proto_msgTypes[21] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *TransferTransactions) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*TransferTransactions) ProtoMessage() {} + +func (x *TransferTransactions) ProtoReflect() protoreflect.Message { + mi := &file_archive_proto_msgTypes[21] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use TransferTransactions.ProtoReflect.Descriptor instead. +func (*TransferTransactions) Descriptor() ([]byte, []int) { + return file_archive_proto_rawDescGZIP(), []int{21} +} + +func (x *TransferTransactions) GetTransferTransactionsPerTick() []*TransferTransactionsPerTick { + if x != nil { + return x.TransferTransactionsPerTick + } + return nil +} + type GetIdentityInfoRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -1307,7 +1409,7 @@ type GetIdentityInfoRequest struct { func (x *GetIdentityInfoRequest) Reset() { *x = GetIdentityInfoRequest{} if protoimpl.UnsafeEnabled { - mi := &file_archive_proto_msgTypes[20] + mi := &file_archive_proto_msgTypes[22] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1320,7 +1422,7 @@ func (x *GetIdentityInfoRequest) String() string { func (*GetIdentityInfoRequest) ProtoMessage() {} func (x *GetIdentityInfoRequest) ProtoReflect() protoreflect.Message { - mi := &file_archive_proto_msgTypes[20] + mi := &file_archive_proto_msgTypes[22] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1333,7 +1435,7 @@ func (x *GetIdentityInfoRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GetIdentityInfoRequest.ProtoReflect.Descriptor instead. func (*GetIdentityInfoRequest) Descriptor() ([]byte, []int) { - return file_archive_proto_rawDescGZIP(), []int{20} + return file_archive_proto_rawDescGZIP(), []int{22} } func (x *GetIdentityInfoRequest) GetIdentity() string { @@ -1354,7 +1456,7 @@ type GetIdentityInfoResponse struct { func (x *GetIdentityInfoResponse) Reset() { *x = GetIdentityInfoResponse{} if protoimpl.UnsafeEnabled { - mi := &file_archive_proto_msgTypes[21] + mi := &file_archive_proto_msgTypes[23] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1367,7 +1469,7 @@ func (x *GetIdentityInfoResponse) String() string { func (*GetIdentityInfoResponse) ProtoMessage() {} func (x *GetIdentityInfoResponse) ProtoReflect() protoreflect.Message { - mi := &file_archive_proto_msgTypes[21] + mi := &file_archive_proto_msgTypes[23] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1380,7 +1482,7 @@ func (x *GetIdentityInfoResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use GetIdentityInfoResponse.ProtoReflect.Descriptor instead. func (*GetIdentityInfoResponse) Descriptor() ([]byte, []int) { - return file_archive_proto_rawDescGZIP(), []int{21} + return file_archive_proto_rawDescGZIP(), []int{23} } func (x *GetIdentityInfoResponse) GetIdentityInfo() *IdentityInfo { @@ -1399,7 +1501,7 @@ type GetLastProcessedTickRequest struct { func (x *GetLastProcessedTickRequest) Reset() { *x = GetLastProcessedTickRequest{} if protoimpl.UnsafeEnabled { - mi := &file_archive_proto_msgTypes[22] + mi := &file_archive_proto_msgTypes[24] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1412,7 +1514,7 @@ func (x *GetLastProcessedTickRequest) String() string { func (*GetLastProcessedTickRequest) ProtoMessage() {} func (x *GetLastProcessedTickRequest) ProtoReflect() protoreflect.Message { - mi := &file_archive_proto_msgTypes[22] + mi := &file_archive_proto_msgTypes[24] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1425,7 +1527,7 @@ func (x *GetLastProcessedTickRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GetLastProcessedTickRequest.ProtoReflect.Descriptor instead. func (*GetLastProcessedTickRequest) Descriptor() ([]byte, []int) { - return file_archive_proto_rawDescGZIP(), []int{22} + return file_archive_proto_rawDescGZIP(), []int{24} } type GetLastProcessedTickResponse struct { @@ -1440,7 +1542,7 @@ type GetLastProcessedTickResponse struct { func (x *GetLastProcessedTickResponse) Reset() { *x = GetLastProcessedTickResponse{} if protoimpl.UnsafeEnabled { - mi := &file_archive_proto_msgTypes[23] + mi := &file_archive_proto_msgTypes[25] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1453,7 +1555,7 @@ func (x *GetLastProcessedTickResponse) String() string { func (*GetLastProcessedTickResponse) ProtoMessage() {} func (x *GetLastProcessedTickResponse) ProtoReflect() protoreflect.Message { - mi := &file_archive_proto_msgTypes[23] + mi := &file_archive_proto_msgTypes[25] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1466,7 +1568,7 @@ func (x *GetLastProcessedTickResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use GetLastProcessedTickResponse.ProtoReflect.Descriptor instead. func (*GetLastProcessedTickResponse) Descriptor() ([]byte, []int) { - return file_archive_proto_rawDescGZIP(), []int{23} + return file_archive_proto_rawDescGZIP(), []int{25} } func (x *GetLastProcessedTickResponse) GetLastProcessedTick() uint32 { @@ -1494,7 +1596,7 @@ type SendRawTransactionRequest struct { func (x *SendRawTransactionRequest) Reset() { *x = SendRawTransactionRequest{} if protoimpl.UnsafeEnabled { - mi := &file_archive_proto_msgTypes[24] + mi := &file_archive_proto_msgTypes[26] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1507,7 +1609,7 @@ func (x *SendRawTransactionRequest) String() string { func (*SendRawTransactionRequest) ProtoMessage() {} func (x *SendRawTransactionRequest) ProtoReflect() protoreflect.Message { - mi := &file_archive_proto_msgTypes[24] + mi := &file_archive_proto_msgTypes[26] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1520,7 +1622,7 @@ func (x *SendRawTransactionRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use SendRawTransactionRequest.ProtoReflect.Descriptor instead. func (*SendRawTransactionRequest) Descriptor() ([]byte, []int) { - return file_archive_proto_rawDescGZIP(), []int{24} + return file_archive_proto_rawDescGZIP(), []int{26} } func (x *SendRawTransactionRequest) GetSignedTx() string { @@ -1541,7 +1643,7 @@ type SendRawTransactionResponse struct { func (x *SendRawTransactionResponse) Reset() { *x = SendRawTransactionResponse{} if protoimpl.UnsafeEnabled { - mi := &file_archive_proto_msgTypes[25] + mi := &file_archive_proto_msgTypes[27] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1554,7 +1656,7 @@ func (x *SendRawTransactionResponse) String() string { func (*SendRawTransactionResponse) ProtoMessage() {} func (x *SendRawTransactionResponse) ProtoReflect() protoreflect.Message { - mi := &file_archive_proto_msgTypes[25] + mi := &file_archive_proto_msgTypes[27] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1567,7 +1669,7 @@ func (x *SendRawTransactionResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use SendRawTransactionResponse.ProtoReflect.Descriptor instead. func (*SendRawTransactionResponse) Descriptor() ([]byte, []int) { - return file_archive_proto_rawDescGZIP(), []int{25} + return file_archive_proto_rawDescGZIP(), []int{27} } func (x *SendRawTransactionResponse) GetMessage() string { @@ -1586,7 +1688,7 @@ type GetSkippedTicksRequest struct { func (x *GetSkippedTicksRequest) Reset() { *x = GetSkippedTicksRequest{} if protoimpl.UnsafeEnabled { - mi := &file_archive_proto_msgTypes[26] + mi := &file_archive_proto_msgTypes[28] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1599,7 +1701,7 @@ func (x *GetSkippedTicksRequest) String() string { func (*GetSkippedTicksRequest) ProtoMessage() {} func (x *GetSkippedTicksRequest) ProtoReflect() protoreflect.Message { - mi := &file_archive_proto_msgTypes[26] + mi := &file_archive_proto_msgTypes[28] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1612,7 +1714,7 @@ func (x *GetSkippedTicksRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GetSkippedTicksRequest.ProtoReflect.Descriptor instead. func (*GetSkippedTicksRequest) Descriptor() ([]byte, []int) { - return file_archive_proto_rawDescGZIP(), []int{26} + return file_archive_proto_rawDescGZIP(), []int{28} } type GetSkippedTicksResponse struct { @@ -1626,7 +1728,7 @@ type GetSkippedTicksResponse struct { func (x *GetSkippedTicksResponse) Reset() { *x = GetSkippedTicksResponse{} if protoimpl.UnsafeEnabled { - mi := &file_archive_proto_msgTypes[27] + mi := &file_archive_proto_msgTypes[29] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1639,7 +1741,7 @@ func (x *GetSkippedTicksResponse) String() string { func (*GetSkippedTicksResponse) ProtoMessage() {} func (x *GetSkippedTicksResponse) ProtoReflect() protoreflect.Message { - mi := &file_archive_proto_msgTypes[27] + mi := &file_archive_proto_msgTypes[29] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1652,7 +1754,7 @@ func (x *GetSkippedTicksResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use GetSkippedTicksResponse.ProtoReflect.Descriptor instead. func (*GetSkippedTicksResponse) Descriptor() ([]byte, []int) { - return file_archive_proto_rawDescGZIP(), []int{27} + return file_archive_proto_rawDescGZIP(), []int{29} } func (x *GetSkippedTicksResponse) GetSkippedTicks() []*SkippedTicksInterval { @@ -1662,6 +1764,202 @@ func (x *GetSkippedTicksResponse) GetSkippedTicks() []*SkippedTicksInterval { return nil } +type GetTransferTransactionsRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Identity string `protobuf:"bytes,1,opt,name=identity,proto3" json:"identity,omitempty"` +} + +func (x *GetTransferTransactionsRequest) Reset() { + *x = GetTransferTransactionsRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_archive_proto_msgTypes[30] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetTransferTransactionsRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetTransferTransactionsRequest) ProtoMessage() {} + +func (x *GetTransferTransactionsRequest) ProtoReflect() protoreflect.Message { + mi := &file_archive_proto_msgTypes[30] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetTransferTransactionsRequest.ProtoReflect.Descriptor instead. +func (*GetTransferTransactionsRequest) Descriptor() ([]byte, []int) { + return file_archive_proto_rawDescGZIP(), []int{30} +} + +func (x *GetTransferTransactionsRequest) GetIdentity() string { + if x != nil { + return x.Identity + } + return "" +} + +type GetTransferTransactionsResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + TransferTransactions *TransferTransactions `protobuf:"bytes,1,opt,name=transfer_transactions,json=transferTransactions,proto3" json:"transfer_transactions,omitempty"` +} + +func (x *GetTransferTransactionsResponse) Reset() { + *x = GetTransferTransactionsResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_archive_proto_msgTypes[31] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetTransferTransactionsResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetTransferTransactionsResponse) ProtoMessage() {} + +func (x *GetTransferTransactionsResponse) ProtoReflect() protoreflect.Message { + mi := &file_archive_proto_msgTypes[31] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetTransferTransactionsResponse.ProtoReflect.Descriptor instead. +func (*GetTransferTransactionsResponse) Descriptor() ([]byte, []int) { + return file_archive_proto_rawDescGZIP(), []int{31} +} + +func (x *GetTransferTransactionsResponse) GetTransferTransactions() *TransferTransactions { + if x != nil { + return x.TransferTransactions + } + return nil +} + +type GetTransferTransactionsPerTickRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Identity string `protobuf:"bytes,1,opt,name=identity,proto3" json:"identity,omitempty"` + TickNumber uint32 `protobuf:"varint,2,opt,name=tick_number,json=tickNumber,proto3" json:"tick_number,omitempty"` +} + +func (x *GetTransferTransactionsPerTickRequest) Reset() { + *x = GetTransferTransactionsPerTickRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_archive_proto_msgTypes[32] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetTransferTransactionsPerTickRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetTransferTransactionsPerTickRequest) ProtoMessage() {} + +func (x *GetTransferTransactionsPerTickRequest) ProtoReflect() protoreflect.Message { + mi := &file_archive_proto_msgTypes[32] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetTransferTransactionsPerTickRequest.ProtoReflect.Descriptor instead. +func (*GetTransferTransactionsPerTickRequest) Descriptor() ([]byte, []int) { + return file_archive_proto_rawDescGZIP(), []int{32} +} + +func (x *GetTransferTransactionsPerTickRequest) GetIdentity() string { + if x != nil { + return x.Identity + } + return "" +} + +func (x *GetTransferTransactionsPerTickRequest) GetTickNumber() uint32 { + if x != nil { + return x.TickNumber + } + return 0 +} + +type GetTransferTransactionsPerTickResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + TransferTransactionsPerTick *TransferTransactionsPerTick `protobuf:"bytes,1,opt,name=transfer_transactions_per_tick,json=transferTransactionsPerTick,proto3" json:"transfer_transactions_per_tick,omitempty"` +} + +func (x *GetTransferTransactionsPerTickResponse) Reset() { + *x = GetTransferTransactionsPerTickResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_archive_proto_msgTypes[33] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetTransferTransactionsPerTickResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetTransferTransactionsPerTickResponse) ProtoMessage() {} + +func (x *GetTransferTransactionsPerTickResponse) ProtoReflect() protoreflect.Message { + mi := &file_archive_proto_msgTypes[33] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetTransferTransactionsPerTickResponse.ProtoReflect.Descriptor instead. +func (*GetTransferTransactionsPerTickResponse) Descriptor() ([]byte, []int) { + return file_archive_proto_rawDescGZIP(), []int{33} +} + +func (x *GetTransferTransactionsPerTickResponse) GetTransferTransactionsPerTick() *TransferTransactionsPerTick { + if x != nil { + return x.TransferTransactionsPerTick + } + return nil +} + var File_archive_proto protoreflect.FileDescriptor var file_archive_proto_rawDesc = []byte{ @@ -1878,128 +2176,196 @@ var file_archive_proto_rawDesc = []byte{ 0x6e, 0x67, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x54, 0x69, 0x63, 0x6b, 0x12, 0x21, 0x0a, 0x0c, 0x73, 0x69, 0x62, 0x6c, 0x69, 0x6e, 0x67, 0x73, 0x5f, 0x68, 0x65, 0x78, 0x18, 0x0a, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0b, 0x73, 0x69, 0x62, 0x6c, 0x69, 0x6e, 0x67, 0x73, 0x48, 0x65, - 0x78, 0x22, 0x34, 0x0a, 0x16, 0x47, 0x65, 0x74, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, - 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x69, - 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x69, - 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x22, 0x67, 0x0a, 0x17, 0x47, 0x65, 0x74, 0x49, 0x64, - 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x12, 0x4c, 0x0a, 0x0d, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x5f, 0x69, - 0x6e, 0x66, 0x6f, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x71, 0x75, 0x62, 0x69, - 0x63, 0x2e, 0x61, 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, 0x72, 0x2e, 0x61, 0x72, 0x63, 0x68, 0x69, - 0x76, 0x65, 0x2e, 0x70, 0x62, 0x2e, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x49, 0x6e, - 0x66, 0x6f, 0x52, 0x0c, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x49, 0x6e, 0x66, 0x6f, - 0x22, 0x1d, 0x0a, 0x1b, 0x47, 0x65, 0x74, 0x4c, 0x61, 0x73, 0x74, 0x50, 0x72, 0x6f, 0x63, 0x65, - 0x73, 0x73, 0x65, 0x64, 0x54, 0x69, 0x63, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, - 0xbb, 0x02, 0x0a, 0x1c, 0x47, 0x65, 0x74, 0x4c, 0x61, 0x73, 0x74, 0x50, 0x72, 0x6f, 0x63, 0x65, - 0x73, 0x73, 0x65, 0x64, 0x54, 0x69, 0x63, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x12, 0x2e, 0x0a, 0x13, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, - 0x65, 0x64, 0x5f, 0x74, 0x69, 0x63, 0x6b, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x11, 0x6c, - 0x61, 0x73, 0x74, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x65, 0x64, 0x54, 0x69, 0x63, 0x6b, - 0x12, 0x9b, 0x01, 0x0a, 0x1e, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, - 0x73, 0x65, 0x64, 0x5f, 0x74, 0x69, 0x63, 0x6b, 0x73, 0x5f, 0x70, 0x65, 0x72, 0x5f, 0x65, 0x70, - 0x6f, 0x63, 0x68, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x57, 0x2e, 0x71, 0x75, 0x62, 0x69, - 0x63, 0x2e, 0x61, 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, 0x72, 0x2e, 0x61, 0x72, 0x63, 0x68, 0x69, - 0x76, 0x65, 0x2e, 0x70, 0x62, 0x2e, 0x47, 0x65, 0x74, 0x4c, 0x61, 0x73, 0x74, 0x50, 0x72, 0x6f, - 0x63, 0x65, 0x73, 0x73, 0x65, 0x64, 0x54, 0x69, 0x63, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x2e, 0x4c, 0x61, 0x73, 0x74, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x65, 0x64, - 0x54, 0x69, 0x63, 0x6b, 0x73, 0x50, 0x65, 0x72, 0x45, 0x70, 0x6f, 0x63, 0x68, 0x45, 0x6e, 0x74, - 0x72, 0x79, 0x52, 0x1a, 0x6c, 0x61, 0x73, 0x74, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x65, - 0x64, 0x54, 0x69, 0x63, 0x6b, 0x73, 0x50, 0x65, 0x72, 0x45, 0x70, 0x6f, 0x63, 0x68, 0x1a, 0x4d, - 0x0a, 0x1f, 0x4c, 0x61, 0x73, 0x74, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x65, 0x64, 0x54, - 0x69, 0x63, 0x6b, 0x73, 0x50, 0x65, 0x72, 0x45, 0x70, 0x6f, 0x63, 0x68, 0x45, 0x6e, 0x74, 0x72, - 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x03, - 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x04, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x38, 0x0a, - 0x19, 0x53, 0x65, 0x6e, 0x64, 0x52, 0x61, 0x77, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, - 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x73, 0x69, - 0x67, 0x6e, 0x65, 0x64, 0x5f, 0x74, 0x78, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x73, - 0x69, 0x67, 0x6e, 0x65, 0x64, 0x54, 0x78, 0x22, 0x36, 0x0a, 0x1a, 0x53, 0x65, 0x6e, 0x64, 0x52, - 0x61, 0x77, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, - 0x18, 0x0a, 0x16, 0x47, 0x65, 0x74, 0x53, 0x6b, 0x69, 0x70, 0x70, 0x65, 0x64, 0x54, 0x69, 0x63, - 0x6b, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x6f, 0x0a, 0x17, 0x47, 0x65, 0x74, - 0x53, 0x6b, 0x69, 0x70, 0x70, 0x65, 0x64, 0x54, 0x69, 0x63, 0x6b, 0x73, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x54, 0x0a, 0x0d, 0x73, 0x6b, 0x69, 0x70, 0x70, 0x65, 0x64, 0x5f, - 0x74, 0x69, 0x63, 0x6b, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2f, 0x2e, 0x71, 0x75, - 0x62, 0x69, 0x63, 0x2e, 0x61, 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, 0x72, 0x2e, 0x61, 0x72, 0x63, - 0x68, 0x69, 0x76, 0x65, 0x2e, 0x70, 0x62, 0x2e, 0x53, 0x6b, 0x69, 0x70, 0x70, 0x65, 0x64, 0x54, - 0x69, 0x63, 0x6b, 0x73, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x52, 0x0c, 0x73, 0x6b, - 0x69, 0x70, 0x70, 0x65, 0x64, 0x54, 0x69, 0x63, 0x6b, 0x73, 0x32, 0xef, 0x08, 0x0a, 0x0e, 0x41, - 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x6c, 0x0a, - 0x0b, 0x47, 0x65, 0x74, 0x54, 0x69, 0x63, 0x6b, 0x44, 0x61, 0x74, 0x61, 0x12, 0x2d, 0x2e, 0x71, - 0x75, 0x62, 0x69, 0x63, 0x2e, 0x61, 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, 0x72, 0x2e, 0x61, 0x72, - 0x63, 0x68, 0x69, 0x76, 0x65, 0x2e, 0x70, 0x62, 0x2e, 0x47, 0x65, 0x74, 0x54, 0x69, 0x63, 0x6b, - 0x44, 0x61, 0x74, 0x61, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2e, 0x2e, 0x71, 0x75, - 0x62, 0x69, 0x63, 0x2e, 0x61, 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, 0x72, 0x2e, 0x61, 0x72, 0x63, - 0x68, 0x69, 0x76, 0x65, 0x2e, 0x70, 0x62, 0x2e, 0x47, 0x65, 0x74, 0x54, 0x69, 0x63, 0x6b, 0x44, - 0x61, 0x74, 0x61, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x84, 0x01, 0x0a, 0x13, - 0x47, 0x65, 0x74, 0x54, 0x69, 0x63, 0x6b, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, - 0x6f, 0x6e, 0x73, 0x12, 0x35, 0x2e, 0x71, 0x75, 0x62, 0x69, 0x63, 0x2e, 0x61, 0x72, 0x63, 0x68, - 0x69, 0x76, 0x65, 0x72, 0x2e, 0x61, 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, 0x2e, 0x70, 0x62, 0x2e, - 0x47, 0x65, 0x74, 0x54, 0x69, 0x63, 0x6b, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, - 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x36, 0x2e, 0x71, 0x75, 0x62, - 0x69, 0x63, 0x2e, 0x61, 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, 0x72, 0x2e, 0x61, 0x72, 0x63, 0x68, - 0x69, 0x76, 0x65, 0x2e, 0x70, 0x62, 0x2e, 0x47, 0x65, 0x74, 0x54, 0x69, 0x63, 0x6b, 0x54, 0x72, - 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x12, 0x75, 0x0a, 0x0e, 0x47, 0x65, 0x74, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, - 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x30, 0x2e, 0x71, 0x75, 0x62, 0x69, 0x63, 0x2e, 0x61, 0x72, 0x63, - 0x68, 0x69, 0x76, 0x65, 0x72, 0x2e, 0x61, 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, 0x2e, 0x70, 0x62, - 0x2e, 0x47, 0x65, 0x74, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x31, 0x2e, 0x71, 0x75, 0x62, 0x69, 0x63, 0x2e, 0x61, - 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, 0x72, 0x2e, 0x61, 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, 0x2e, - 0x70, 0x62, 0x2e, 0x47, 0x65, 0x74, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, - 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x7e, 0x0a, 0x11, 0x47, 0x65, 0x74, - 0x51, 0x75, 0x6f, 0x72, 0x75, 0x6d, 0x54, 0x69, 0x63, 0x6b, 0x44, 0x61, 0x74, 0x61, 0x12, 0x33, - 0x2e, 0x71, 0x75, 0x62, 0x69, 0x63, 0x2e, 0x61, 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, 0x72, 0x2e, - 0x61, 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, 0x2e, 0x70, 0x62, 0x2e, 0x47, 0x65, 0x74, 0x51, 0x75, - 0x6f, 0x72, 0x75, 0x6d, 0x54, 0x69, 0x63, 0x6b, 0x44, 0x61, 0x74, 0x61, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x1a, 0x34, 0x2e, 0x71, 0x75, 0x62, 0x69, 0x63, 0x2e, 0x61, 0x72, 0x63, 0x68, - 0x69, 0x76, 0x65, 0x72, 0x2e, 0x61, 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, 0x2e, 0x70, 0x62, 0x2e, - 0x47, 0x65, 0x74, 0x51, 0x75, 0x6f, 0x72, 0x75, 0x6d, 0x54, 0x69, 0x63, 0x6b, 0x44, 0x61, 0x74, - 0x61, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x6f, 0x0a, 0x0c, 0x47, 0x65, 0x74, - 0x43, 0x6f, 0x6d, 0x70, 0x75, 0x74, 0x6f, 0x72, 0x73, 0x12, 0x2e, 0x2e, 0x71, 0x75, 0x62, 0x69, - 0x63, 0x2e, 0x61, 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, 0x72, 0x2e, 0x61, 0x72, 0x63, 0x68, 0x69, - 0x76, 0x65, 0x2e, 0x70, 0x62, 0x2e, 0x47, 0x65, 0x74, 0x43, 0x6f, 0x6d, 0x70, 0x75, 0x74, 0x6f, - 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2f, 0x2e, 0x71, 0x75, 0x62, 0x69, - 0x63, 0x2e, 0x61, 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, 0x72, 0x2e, 0x61, 0x72, 0x63, 0x68, 0x69, - 0x76, 0x65, 0x2e, 0x70, 0x62, 0x2e, 0x47, 0x65, 0x74, 0x43, 0x6f, 0x6d, 0x70, 0x75, 0x74, 0x6f, - 0x72, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x78, 0x0a, 0x0f, 0x47, 0x65, - 0x74, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x31, 0x2e, + 0x78, 0x22, 0x8b, 0x01, 0x0a, 0x1b, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x54, 0x72, + 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x50, 0x65, 0x72, 0x54, 0x69, 0x63, + 0x6b, 0x12, 0x1f, 0x0a, 0x0b, 0x74, 0x69, 0x63, 0x6b, 0x5f, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0a, 0x74, 0x69, 0x63, 0x6b, 0x4e, 0x75, 0x6d, 0x62, + 0x65, 0x72, 0x12, 0x4b, 0x0a, 0x0c, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x71, 0x75, 0x62, 0x69, 0x63, + 0x2e, 0x61, 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, 0x72, 0x2e, 0x61, 0x72, 0x63, 0x68, 0x69, 0x76, + 0x65, 0x2e, 0x70, 0x62, 0x2e, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x73, 0x52, 0x0c, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, + 0x93, 0x01, 0x0a, 0x14, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x54, 0x72, 0x61, 0x6e, + 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x7b, 0x0a, 0x1e, 0x74, 0x72, 0x61, 0x6e, + 0x73, 0x66, 0x65, 0x72, 0x5f, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x73, 0x5f, 0x70, 0x65, 0x72, 0x5f, 0x74, 0x69, 0x63, 0x6b, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, + 0x32, 0x36, 0x2e, 0x71, 0x75, 0x62, 0x69, 0x63, 0x2e, 0x61, 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, + 0x72, 0x2e, 0x61, 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, 0x2e, 0x70, 0x62, 0x2e, 0x54, 0x72, 0x61, + 0x6e, 0x73, 0x66, 0x65, 0x72, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x73, 0x50, 0x65, 0x72, 0x54, 0x69, 0x63, 0x6b, 0x52, 0x1b, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, + 0x65, 0x72, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x50, 0x65, + 0x72, 0x54, 0x69, 0x63, 0x6b, 0x22, 0x34, 0x0a, 0x16, 0x47, 0x65, 0x74, 0x49, 0x64, 0x65, 0x6e, + 0x74, 0x69, 0x74, 0x79, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, + 0x1a, 0x0a, 0x08, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x08, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x22, 0x67, 0x0a, 0x17, 0x47, + 0x65, 0x74, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4c, 0x0a, 0x0d, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, + 0x74, 0x79, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x71, 0x75, 0x62, 0x69, 0x63, 0x2e, 0x61, 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, 0x72, 0x2e, 0x61, - 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, 0x2e, 0x70, 0x62, 0x2e, 0x47, 0x65, 0x74, 0x49, 0x64, 0x65, - 0x6e, 0x74, 0x69, 0x74, 0x79, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x1a, 0x32, 0x2e, 0x71, 0x75, 0x62, 0x69, 0x63, 0x2e, 0x61, 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, - 0x72, 0x2e, 0x61, 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, 0x2e, 0x70, 0x62, 0x2e, 0x47, 0x65, 0x74, - 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x87, 0x01, 0x0a, 0x14, 0x47, 0x65, 0x74, 0x4c, 0x61, 0x73, 0x74, - 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x65, 0x64, 0x54, 0x69, 0x63, 0x6b, 0x12, 0x36, 0x2e, + 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, 0x2e, 0x70, 0x62, 0x2e, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, + 0x74, 0x79, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x0c, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, + 0x49, 0x6e, 0x66, 0x6f, 0x22, 0x1d, 0x0a, 0x1b, 0x47, 0x65, 0x74, 0x4c, 0x61, 0x73, 0x74, 0x50, + 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x65, 0x64, 0x54, 0x69, 0x63, 0x6b, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x22, 0xbb, 0x02, 0x0a, 0x1c, 0x47, 0x65, 0x74, 0x4c, 0x61, 0x73, 0x74, 0x50, + 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x65, 0x64, 0x54, 0x69, 0x63, 0x6b, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2e, 0x0a, 0x13, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x70, 0x72, 0x6f, + 0x63, 0x65, 0x73, 0x73, 0x65, 0x64, 0x5f, 0x74, 0x69, 0x63, 0x6b, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x0d, 0x52, 0x11, 0x6c, 0x61, 0x73, 0x74, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x65, 0x64, + 0x54, 0x69, 0x63, 0x6b, 0x12, 0x9b, 0x01, 0x0a, 0x1e, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x70, 0x72, + 0x6f, 0x63, 0x65, 0x73, 0x73, 0x65, 0x64, 0x5f, 0x74, 0x69, 0x63, 0x6b, 0x73, 0x5f, 0x70, 0x65, + 0x72, 0x5f, 0x65, 0x70, 0x6f, 0x63, 0x68, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x57, 0x2e, 0x71, 0x75, 0x62, 0x69, 0x63, 0x2e, 0x61, 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, 0x72, 0x2e, 0x61, 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, 0x2e, 0x70, 0x62, 0x2e, 0x47, 0x65, 0x74, 0x4c, 0x61, 0x73, 0x74, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x65, 0x64, 0x54, 0x69, 0x63, 0x6b, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x37, 0x2e, 0x71, 0x75, 0x62, 0x69, 0x63, 0x2e, 0x61, 0x72, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x4c, 0x61, 0x73, 0x74, 0x50, 0x72, 0x6f, 0x63, 0x65, + 0x73, 0x73, 0x65, 0x64, 0x54, 0x69, 0x63, 0x6b, 0x73, 0x50, 0x65, 0x72, 0x45, 0x70, 0x6f, 0x63, + 0x68, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x1a, 0x6c, 0x61, 0x73, 0x74, 0x50, 0x72, 0x6f, 0x63, + 0x65, 0x73, 0x73, 0x65, 0x64, 0x54, 0x69, 0x63, 0x6b, 0x73, 0x50, 0x65, 0x72, 0x45, 0x70, 0x6f, + 0x63, 0x68, 0x1a, 0x4d, 0x0a, 0x1f, 0x4c, 0x61, 0x73, 0x74, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, + 0x73, 0x65, 0x64, 0x54, 0x69, 0x63, 0x6b, 0x73, 0x50, 0x65, 0x72, 0x45, 0x70, 0x6f, 0x63, 0x68, + 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x0d, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, + 0x01, 0x22, 0x38, 0x0a, 0x19, 0x53, 0x65, 0x6e, 0x64, 0x52, 0x61, 0x77, 0x54, 0x72, 0x61, 0x6e, + 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1b, + 0x0a, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x5f, 0x74, 0x78, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x08, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x54, 0x78, 0x22, 0x36, 0x0a, 0x1a, 0x53, + 0x65, 0x6e, 0x64, 0x52, 0x61, 0x77, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, + 0x73, 0x61, 0x67, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, + 0x61, 0x67, 0x65, 0x22, 0x18, 0x0a, 0x16, 0x47, 0x65, 0x74, 0x53, 0x6b, 0x69, 0x70, 0x70, 0x65, + 0x64, 0x54, 0x69, 0x63, 0x6b, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x6f, 0x0a, + 0x17, 0x47, 0x65, 0x74, 0x53, 0x6b, 0x69, 0x70, 0x70, 0x65, 0x64, 0x54, 0x69, 0x63, 0x6b, 0x73, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x54, 0x0a, 0x0d, 0x73, 0x6b, 0x69, 0x70, + 0x70, 0x65, 0x64, 0x5f, 0x74, 0x69, 0x63, 0x6b, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, + 0x2f, 0x2e, 0x71, 0x75, 0x62, 0x69, 0x63, 0x2e, 0x61, 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, 0x72, + 0x2e, 0x61, 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, 0x2e, 0x70, 0x62, 0x2e, 0x53, 0x6b, 0x69, 0x70, + 0x70, 0x65, 0x64, 0x54, 0x69, 0x63, 0x6b, 0x73, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, + 0x52, 0x0c, 0x73, 0x6b, 0x69, 0x70, 0x70, 0x65, 0x64, 0x54, 0x69, 0x63, 0x6b, 0x73, 0x22, 0x3c, + 0x0a, 0x1e, 0x47, 0x65, 0x74, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x54, 0x72, 0x61, + 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x12, 0x1a, 0x0a, 0x08, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x08, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x22, 0x87, 0x01, 0x0a, + 0x1f, 0x47, 0x65, 0x74, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x54, 0x72, 0x61, 0x6e, + 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x12, 0x64, 0x0a, 0x15, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x5f, 0x74, 0x72, 0x61, + 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x2f, 0x2e, 0x71, 0x75, 0x62, 0x69, 0x63, 0x2e, 0x61, 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, 0x72, + 0x2e, 0x61, 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, 0x2e, 0x70, 0x62, 0x2e, 0x54, 0x72, 0x61, 0x6e, + 0x73, 0x66, 0x65, 0x72, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, + 0x52, 0x14, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0x64, 0x0a, 0x25, 0x47, 0x65, 0x74, 0x54, 0x72, 0x61, + 0x6e, 0x73, 0x66, 0x65, 0x72, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x73, 0x50, 0x65, 0x72, 0x54, 0x69, 0x63, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, + 0x1a, 0x0a, 0x08, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x08, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x12, 0x1f, 0x0a, 0x0b, 0x74, + 0x69, 0x63, 0x6b, 0x5f, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, + 0x52, 0x0a, 0x74, 0x69, 0x63, 0x6b, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x22, 0xa5, 0x01, 0x0a, + 0x26, 0x47, 0x65, 0x74, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x54, 0x72, 0x61, 0x6e, + 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x50, 0x65, 0x72, 0x54, 0x69, 0x63, 0x6b, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x7b, 0x0a, 0x1e, 0x74, 0x72, 0x61, 0x6e, 0x73, + 0x66, 0x65, 0x72, 0x5f, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, + 0x5f, 0x70, 0x65, 0x72, 0x5f, 0x74, 0x69, 0x63, 0x6b, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x36, 0x2e, 0x71, 0x75, 0x62, 0x69, 0x63, 0x2e, 0x61, 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, 0x72, + 0x2e, 0x61, 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, 0x2e, 0x70, 0x62, 0x2e, 0x54, 0x72, 0x61, 0x6e, + 0x73, 0x66, 0x65, 0x72, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, + 0x50, 0x65, 0x72, 0x54, 0x69, 0x63, 0x6b, 0x52, 0x1b, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, + 0x72, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x50, 0x65, 0x72, + 0x54, 0x69, 0x63, 0x6b, 0x32, 0xaa, 0x0b, 0x0a, 0x0e, 0x41, 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, + 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x6c, 0x0a, 0x0b, 0x47, 0x65, 0x74, 0x54, 0x69, + 0x63, 0x6b, 0x44, 0x61, 0x74, 0x61, 0x12, 0x2d, 0x2e, 0x71, 0x75, 0x62, 0x69, 0x63, 0x2e, 0x61, + 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, 0x72, 0x2e, 0x61, 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, 0x2e, + 0x70, 0x62, 0x2e, 0x47, 0x65, 0x74, 0x54, 0x69, 0x63, 0x6b, 0x44, 0x61, 0x74, 0x61, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2e, 0x2e, 0x71, 0x75, 0x62, 0x69, 0x63, 0x2e, 0x61, 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, 0x72, 0x2e, 0x61, 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, 0x2e, 0x70, - 0x62, 0x2e, 0x47, 0x65, 0x74, 0x4c, 0x61, 0x73, 0x74, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, - 0x65, 0x64, 0x54, 0x69, 0x63, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x81, - 0x01, 0x0a, 0x12, 0x53, 0x65, 0x6e, 0x64, 0x52, 0x61, 0x77, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, - 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x34, 0x2e, 0x71, 0x75, 0x62, 0x69, 0x63, 0x2e, 0x61, 0x72, + 0x62, 0x2e, 0x47, 0x65, 0x74, 0x54, 0x69, 0x63, 0x6b, 0x44, 0x61, 0x74, 0x61, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x84, 0x01, 0x0a, 0x13, 0x47, 0x65, 0x74, 0x54, 0x69, 0x63, + 0x6b, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x35, 0x2e, + 0x71, 0x75, 0x62, 0x69, 0x63, 0x2e, 0x61, 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, 0x72, 0x2e, 0x61, + 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, 0x2e, 0x70, 0x62, 0x2e, 0x47, 0x65, 0x74, 0x54, 0x69, 0x63, + 0x6b, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x1a, 0x36, 0x2e, 0x71, 0x75, 0x62, 0x69, 0x63, 0x2e, 0x61, 0x72, 0x63, + 0x68, 0x69, 0x76, 0x65, 0x72, 0x2e, 0x61, 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, 0x2e, 0x70, 0x62, + 0x2e, 0x47, 0x65, 0x74, 0x54, 0x69, 0x63, 0x6b, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x75, 0x0a, 0x0e, + 0x47, 0x65, 0x74, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x30, + 0x2e, 0x71, 0x75, 0x62, 0x69, 0x63, 0x2e, 0x61, 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, 0x72, 0x2e, + 0x61, 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, 0x2e, 0x70, 0x62, 0x2e, 0x47, 0x65, 0x74, 0x54, 0x72, + 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x1a, 0x31, 0x2e, 0x71, 0x75, 0x62, 0x69, 0x63, 0x2e, 0x61, 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, + 0x72, 0x2e, 0x61, 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, 0x2e, 0x70, 0x62, 0x2e, 0x47, 0x65, 0x74, + 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x12, 0x7e, 0x0a, 0x11, 0x47, 0x65, 0x74, 0x51, 0x75, 0x6f, 0x72, 0x75, 0x6d, + 0x54, 0x69, 0x63, 0x6b, 0x44, 0x61, 0x74, 0x61, 0x12, 0x33, 0x2e, 0x71, 0x75, 0x62, 0x69, 0x63, + 0x2e, 0x61, 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, 0x72, 0x2e, 0x61, 0x72, 0x63, 0x68, 0x69, 0x76, + 0x65, 0x2e, 0x70, 0x62, 0x2e, 0x47, 0x65, 0x74, 0x51, 0x75, 0x6f, 0x72, 0x75, 0x6d, 0x54, 0x69, + 0x63, 0x6b, 0x44, 0x61, 0x74, 0x61, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x34, 0x2e, + 0x71, 0x75, 0x62, 0x69, 0x63, 0x2e, 0x61, 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, 0x72, 0x2e, 0x61, + 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, 0x2e, 0x70, 0x62, 0x2e, 0x47, 0x65, 0x74, 0x51, 0x75, 0x6f, + 0x72, 0x75, 0x6d, 0x54, 0x69, 0x63, 0x6b, 0x44, 0x61, 0x74, 0x61, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x12, 0x6f, 0x0a, 0x0c, 0x47, 0x65, 0x74, 0x43, 0x6f, 0x6d, 0x70, 0x75, 0x74, + 0x6f, 0x72, 0x73, 0x12, 0x2e, 0x2e, 0x71, 0x75, 0x62, 0x69, 0x63, 0x2e, 0x61, 0x72, 0x63, 0x68, + 0x69, 0x76, 0x65, 0x72, 0x2e, 0x61, 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, 0x2e, 0x70, 0x62, 0x2e, + 0x47, 0x65, 0x74, 0x43, 0x6f, 0x6d, 0x70, 0x75, 0x74, 0x6f, 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x1a, 0x2f, 0x2e, 0x71, 0x75, 0x62, 0x69, 0x63, 0x2e, 0x61, 0x72, 0x63, 0x68, + 0x69, 0x76, 0x65, 0x72, 0x2e, 0x61, 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, 0x2e, 0x70, 0x62, 0x2e, + 0x47, 0x65, 0x74, 0x43, 0x6f, 0x6d, 0x70, 0x75, 0x74, 0x6f, 0x72, 0x73, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x78, 0x0a, 0x0f, 0x47, 0x65, 0x74, 0x49, 0x64, 0x65, 0x6e, 0x74, + 0x69, 0x74, 0x79, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x31, 0x2e, 0x71, 0x75, 0x62, 0x69, 0x63, 0x2e, + 0x61, 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, 0x72, 0x2e, 0x61, 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, + 0x2e, 0x70, 0x62, 0x2e, 0x47, 0x65, 0x74, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x49, + 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x32, 0x2e, 0x71, 0x75, 0x62, + 0x69, 0x63, 0x2e, 0x61, 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, 0x72, 0x2e, 0x61, 0x72, 0x63, 0x68, + 0x69, 0x76, 0x65, 0x2e, 0x70, 0x62, 0x2e, 0x47, 0x65, 0x74, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, + 0x74, 0x79, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x87, + 0x01, 0x0a, 0x14, 0x47, 0x65, 0x74, 0x4c, 0x61, 0x73, 0x74, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, + 0x73, 0x65, 0x64, 0x54, 0x69, 0x63, 0x6b, 0x12, 0x36, 0x2e, 0x71, 0x75, 0x62, 0x69, 0x63, 0x2e, + 0x61, 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, 0x72, 0x2e, 0x61, 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, + 0x2e, 0x70, 0x62, 0x2e, 0x47, 0x65, 0x74, 0x4c, 0x61, 0x73, 0x74, 0x50, 0x72, 0x6f, 0x63, 0x65, + 0x73, 0x73, 0x65, 0x64, 0x54, 0x69, 0x63, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x37, 0x2e, 0x71, 0x75, 0x62, 0x69, 0x63, 0x2e, 0x61, 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, 0x72, + 0x2e, 0x61, 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, 0x2e, 0x70, 0x62, 0x2e, 0x47, 0x65, 0x74, 0x4c, + 0x61, 0x73, 0x74, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x65, 0x64, 0x54, 0x69, 0x63, 0x6b, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x81, 0x01, 0x0a, 0x12, 0x53, 0x65, 0x6e, + 0x64, 0x52, 0x61, 0x77, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, + 0x34, 0x2e, 0x71, 0x75, 0x62, 0x69, 0x63, 0x2e, 0x61, 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, 0x72, + 0x2e, 0x61, 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, 0x2e, 0x70, 0x62, 0x2e, 0x53, 0x65, 0x6e, 0x64, + 0x52, 0x61, 0x77, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x35, 0x2e, 0x71, 0x75, 0x62, 0x69, 0x63, 0x2e, 0x61, 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, 0x72, 0x2e, 0x61, 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, 0x2e, 0x70, 0x62, 0x2e, 0x53, 0x65, 0x6e, 0x64, 0x52, 0x61, 0x77, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, - 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x35, 0x2e, 0x71, 0x75, - 0x62, 0x69, 0x63, 0x2e, 0x61, 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, 0x72, 0x2e, 0x61, 0x72, 0x63, - 0x68, 0x69, 0x76, 0x65, 0x2e, 0x70, 0x62, 0x2e, 0x53, 0x65, 0x6e, 0x64, 0x52, 0x61, 0x77, 0x54, - 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x12, 0x78, 0x0a, 0x0f, 0x47, 0x65, 0x74, 0x53, 0x6b, 0x69, 0x70, 0x70, 0x65, 0x64, - 0x54, 0x69, 0x63, 0x6b, 0x73, 0x12, 0x31, 0x2e, 0x71, 0x75, 0x62, 0x69, 0x63, 0x2e, 0x61, 0x72, - 0x63, 0x68, 0x69, 0x76, 0x65, 0x72, 0x2e, 0x61, 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, 0x2e, 0x70, - 0x62, 0x2e, 0x47, 0x65, 0x74, 0x53, 0x6b, 0x69, 0x70, 0x70, 0x65, 0x64, 0x54, 0x69, 0x63, 0x6b, - 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x32, 0x2e, 0x71, 0x75, 0x62, 0x69, 0x63, - 0x2e, 0x61, 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, 0x72, 0x2e, 0x61, 0x72, 0x63, 0x68, 0x69, 0x76, - 0x65, 0x2e, 0x70, 0x62, 0x2e, 0x47, 0x65, 0x74, 0x53, 0x6b, 0x69, 0x70, 0x70, 0x65, 0x64, 0x54, - 0x69, 0x63, 0x6b, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x29, 0x5a, 0x27, - 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x71, 0x75, 0x62, 0x69, 0x63, - 0x2f, 0x67, 0x6f, 0x2d, 0x61, 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, 0x72, 0x2f, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x62, 0x75, 0x66, 0x66, 0x2f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x78, 0x0a, 0x0f, + 0x47, 0x65, 0x74, 0x53, 0x6b, 0x69, 0x70, 0x70, 0x65, 0x64, 0x54, 0x69, 0x63, 0x6b, 0x73, 0x12, + 0x31, 0x2e, 0x71, 0x75, 0x62, 0x69, 0x63, 0x2e, 0x61, 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, 0x72, + 0x2e, 0x61, 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, 0x2e, 0x70, 0x62, 0x2e, 0x47, 0x65, 0x74, 0x53, + 0x6b, 0x69, 0x70, 0x70, 0x65, 0x64, 0x54, 0x69, 0x63, 0x6b, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x1a, 0x32, 0x2e, 0x71, 0x75, 0x62, 0x69, 0x63, 0x2e, 0x61, 0x72, 0x63, 0x68, 0x69, + 0x76, 0x65, 0x72, 0x2e, 0x61, 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, 0x2e, 0x70, 0x62, 0x2e, 0x47, + 0x65, 0x74, 0x53, 0x6b, 0x69, 0x70, 0x70, 0x65, 0x64, 0x54, 0x69, 0x63, 0x6b, 0x73, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x90, 0x01, 0x0a, 0x17, 0x47, 0x65, 0x74, 0x54, 0x72, + 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x73, 0x12, 0x39, 0x2e, 0x71, 0x75, 0x62, 0x69, 0x63, 0x2e, 0x61, 0x72, 0x63, 0x68, 0x69, + 0x76, 0x65, 0x72, 0x2e, 0x61, 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, 0x2e, 0x70, 0x62, 0x2e, 0x47, + 0x65, 0x74, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x3a, 0x2e, + 0x71, 0x75, 0x62, 0x69, 0x63, 0x2e, 0x61, 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, 0x72, 0x2e, 0x61, + 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, 0x2e, 0x70, 0x62, 0x2e, 0x47, 0x65, 0x74, 0x54, 0x72, 0x61, + 0x6e, 0x73, 0x66, 0x65, 0x72, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0xa5, 0x01, 0x0a, 0x1e, 0x47, 0x65, + 0x74, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x50, 0x65, 0x72, 0x54, 0x69, 0x63, 0x6b, 0x12, 0x40, 0x2e, 0x71, + 0x75, 0x62, 0x69, 0x63, 0x2e, 0x61, 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, 0x72, 0x2e, 0x61, 0x72, + 0x63, 0x68, 0x69, 0x76, 0x65, 0x2e, 0x70, 0x62, 0x2e, 0x47, 0x65, 0x74, 0x54, 0x72, 0x61, 0x6e, + 0x73, 0x66, 0x65, 0x72, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, + 0x50, 0x65, 0x72, 0x54, 0x69, 0x63, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x41, + 0x2e, 0x71, 0x75, 0x62, 0x69, 0x63, 0x2e, 0x61, 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, 0x72, 0x2e, + 0x61, 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, 0x2e, 0x70, 0x62, 0x2e, 0x47, 0x65, 0x74, 0x54, 0x72, + 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x73, 0x50, 0x65, 0x72, 0x54, 0x69, 0x63, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x42, 0x29, 0x5a, 0x27, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, + 0x71, 0x75, 0x62, 0x69, 0x63, 0x2f, 0x67, 0x6f, 0x2d, 0x61, 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, + 0x72, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x66, 0x2f, 0x62, 0x06, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -2014,38 +2380,44 @@ func file_archive_proto_rawDescGZIP() []byte { return file_archive_proto_rawDescData } -var file_archive_proto_msgTypes = make([]protoimpl.MessageInfo, 30) +var file_archive_proto_msgTypes = make([]protoimpl.MessageInfo, 36) var file_archive_proto_goTypes = []interface{}{ - (*TickData)(nil), // 0: qubic.archiver.archive.pb.TickData - (*GetTickDataRequest)(nil), // 1: qubic.archiver.archive.pb.GetTickDataRequest - (*GetTickDataResponse)(nil), // 2: qubic.archiver.archive.pb.GetTickDataResponse - (*Transaction)(nil), // 3: qubic.archiver.archive.pb.Transaction - (*GetTransactionRequest)(nil), // 4: qubic.archiver.archive.pb.GetTransactionRequest - (*GetTransactionResponse)(nil), // 5: qubic.archiver.archive.pb.GetTransactionResponse - (*Transactions)(nil), // 6: qubic.archiver.archive.pb.Transactions - (*GetTickTransactionsRequest)(nil), // 7: qubic.archiver.archive.pb.GetTickTransactionsRequest - (*GetTickTransactionsResponse)(nil), // 8: qubic.archiver.archive.pb.GetTickTransactionsResponse - (*QuorumDiff)(nil), // 9: qubic.archiver.archive.pb.QuorumDiff - (*QuorumTickStructure)(nil), // 10: qubic.archiver.archive.pb.QuorumTickStructure - (*SkippedTicksInterval)(nil), // 11: qubic.archiver.archive.pb.SkippedTicksInterval - (*SkippedTicksIntervalList)(nil), // 12: qubic.archiver.archive.pb.SkippedTicksIntervalList - (*QuorumTickData)(nil), // 13: qubic.archiver.archive.pb.QuorumTickData - (*GetQuorumTickDataRequest)(nil), // 14: qubic.archiver.archive.pb.GetQuorumTickDataRequest - (*GetQuorumTickDataResponse)(nil), // 15: qubic.archiver.archive.pb.GetQuorumTickDataResponse - (*Computors)(nil), // 16: qubic.archiver.archive.pb.Computors - (*GetComputorsRequest)(nil), // 17: qubic.archiver.archive.pb.GetComputorsRequest - (*GetComputorsResponse)(nil), // 18: qubic.archiver.archive.pb.GetComputorsResponse - (*IdentityInfo)(nil), // 19: qubic.archiver.archive.pb.IdentityInfo - (*GetIdentityInfoRequest)(nil), // 20: qubic.archiver.archive.pb.GetIdentityInfoRequest - (*GetIdentityInfoResponse)(nil), // 21: qubic.archiver.archive.pb.GetIdentityInfoResponse - (*GetLastProcessedTickRequest)(nil), // 22: qubic.archiver.archive.pb.GetLastProcessedTickRequest - (*GetLastProcessedTickResponse)(nil), // 23: qubic.archiver.archive.pb.GetLastProcessedTickResponse - (*SendRawTransactionRequest)(nil), // 24: qubic.archiver.archive.pb.SendRawTransactionRequest - (*SendRawTransactionResponse)(nil), // 25: qubic.archiver.archive.pb.SendRawTransactionResponse - (*GetSkippedTicksRequest)(nil), // 26: qubic.archiver.archive.pb.GetSkippedTicksRequest - (*GetSkippedTicksResponse)(nil), // 27: qubic.archiver.archive.pb.GetSkippedTicksResponse - nil, // 28: qubic.archiver.archive.pb.QuorumTickData.QuorumDiffPerComputorEntry - nil, // 29: qubic.archiver.archive.pb.GetLastProcessedTickResponse.LastProcessedTicksPerEpochEntry + (*TickData)(nil), // 0: qubic.archiver.archive.pb.TickData + (*GetTickDataRequest)(nil), // 1: qubic.archiver.archive.pb.GetTickDataRequest + (*GetTickDataResponse)(nil), // 2: qubic.archiver.archive.pb.GetTickDataResponse + (*Transaction)(nil), // 3: qubic.archiver.archive.pb.Transaction + (*GetTransactionRequest)(nil), // 4: qubic.archiver.archive.pb.GetTransactionRequest + (*GetTransactionResponse)(nil), // 5: qubic.archiver.archive.pb.GetTransactionResponse + (*Transactions)(nil), // 6: qubic.archiver.archive.pb.Transactions + (*GetTickTransactionsRequest)(nil), // 7: qubic.archiver.archive.pb.GetTickTransactionsRequest + (*GetTickTransactionsResponse)(nil), // 8: qubic.archiver.archive.pb.GetTickTransactionsResponse + (*QuorumDiff)(nil), // 9: qubic.archiver.archive.pb.QuorumDiff + (*QuorumTickStructure)(nil), // 10: qubic.archiver.archive.pb.QuorumTickStructure + (*SkippedTicksInterval)(nil), // 11: qubic.archiver.archive.pb.SkippedTicksInterval + (*SkippedTicksIntervalList)(nil), // 12: qubic.archiver.archive.pb.SkippedTicksIntervalList + (*QuorumTickData)(nil), // 13: qubic.archiver.archive.pb.QuorumTickData + (*GetQuorumTickDataRequest)(nil), // 14: qubic.archiver.archive.pb.GetQuorumTickDataRequest + (*GetQuorumTickDataResponse)(nil), // 15: qubic.archiver.archive.pb.GetQuorumTickDataResponse + (*Computors)(nil), // 16: qubic.archiver.archive.pb.Computors + (*GetComputorsRequest)(nil), // 17: qubic.archiver.archive.pb.GetComputorsRequest + (*GetComputorsResponse)(nil), // 18: qubic.archiver.archive.pb.GetComputorsResponse + (*IdentityInfo)(nil), // 19: qubic.archiver.archive.pb.IdentityInfo + (*TransferTransactionsPerTick)(nil), // 20: qubic.archiver.archive.pb.TransferTransactionsPerTick + (*TransferTransactions)(nil), // 21: qubic.archiver.archive.pb.TransferTransactions + (*GetIdentityInfoRequest)(nil), // 22: qubic.archiver.archive.pb.GetIdentityInfoRequest + (*GetIdentityInfoResponse)(nil), // 23: qubic.archiver.archive.pb.GetIdentityInfoResponse + (*GetLastProcessedTickRequest)(nil), // 24: qubic.archiver.archive.pb.GetLastProcessedTickRequest + (*GetLastProcessedTickResponse)(nil), // 25: qubic.archiver.archive.pb.GetLastProcessedTickResponse + (*SendRawTransactionRequest)(nil), // 26: qubic.archiver.archive.pb.SendRawTransactionRequest + (*SendRawTransactionResponse)(nil), // 27: qubic.archiver.archive.pb.SendRawTransactionResponse + (*GetSkippedTicksRequest)(nil), // 28: qubic.archiver.archive.pb.GetSkippedTicksRequest + (*GetSkippedTicksResponse)(nil), // 29: qubic.archiver.archive.pb.GetSkippedTicksResponse + (*GetTransferTransactionsRequest)(nil), // 30: qubic.archiver.archive.pb.GetTransferTransactionsRequest + (*GetTransferTransactionsResponse)(nil), // 31: qubic.archiver.archive.pb.GetTransferTransactionsResponse + (*GetTransferTransactionsPerTickRequest)(nil), // 32: qubic.archiver.archive.pb.GetTransferTransactionsPerTickRequest + (*GetTransferTransactionsPerTickResponse)(nil), // 33: qubic.archiver.archive.pb.GetTransferTransactionsPerTickResponse + nil, // 34: qubic.archiver.archive.pb.QuorumTickData.QuorumDiffPerComputorEntry + nil, // 35: qubic.archiver.archive.pb.GetLastProcessedTickResponse.LastProcessedTicksPerEpochEntry } var file_archive_proto_depIdxs = []int32{ 0, // 0: qubic.archiver.archive.pb.GetTickDataResponse.tick_data:type_name -> qubic.archiver.archive.pb.TickData @@ -2054,36 +2426,44 @@ var file_archive_proto_depIdxs = []int32{ 3, // 3: qubic.archiver.archive.pb.GetTickTransactionsResponse.transactions:type_name -> qubic.archiver.archive.pb.Transaction 11, // 4: qubic.archiver.archive.pb.SkippedTicksIntervalList.skipped_ticks:type_name -> qubic.archiver.archive.pb.SkippedTicksInterval 10, // 5: qubic.archiver.archive.pb.QuorumTickData.quorum_tick_structure:type_name -> qubic.archiver.archive.pb.QuorumTickStructure - 28, // 6: qubic.archiver.archive.pb.QuorumTickData.quorum_diff_per_computor:type_name -> qubic.archiver.archive.pb.QuorumTickData.QuorumDiffPerComputorEntry + 34, // 6: qubic.archiver.archive.pb.QuorumTickData.quorum_diff_per_computor:type_name -> qubic.archiver.archive.pb.QuorumTickData.QuorumDiffPerComputorEntry 13, // 7: qubic.archiver.archive.pb.GetQuorumTickDataResponse.quorum_tick_data:type_name -> qubic.archiver.archive.pb.QuorumTickData 16, // 8: qubic.archiver.archive.pb.GetComputorsResponse.computors:type_name -> qubic.archiver.archive.pb.Computors - 19, // 9: qubic.archiver.archive.pb.GetIdentityInfoResponse.identity_info:type_name -> qubic.archiver.archive.pb.IdentityInfo - 29, // 10: qubic.archiver.archive.pb.GetLastProcessedTickResponse.last_processed_ticks_per_epoch:type_name -> qubic.archiver.archive.pb.GetLastProcessedTickResponse.LastProcessedTicksPerEpochEntry - 11, // 11: qubic.archiver.archive.pb.GetSkippedTicksResponse.skipped_ticks:type_name -> qubic.archiver.archive.pb.SkippedTicksInterval - 9, // 12: qubic.archiver.archive.pb.QuorumTickData.QuorumDiffPerComputorEntry.value:type_name -> qubic.archiver.archive.pb.QuorumDiff - 1, // 13: qubic.archiver.archive.pb.ArchiveService.GetTickData:input_type -> qubic.archiver.archive.pb.GetTickDataRequest - 7, // 14: qubic.archiver.archive.pb.ArchiveService.GetTickTransactions:input_type -> qubic.archiver.archive.pb.GetTickTransactionsRequest - 4, // 15: qubic.archiver.archive.pb.ArchiveService.GetTransaction:input_type -> qubic.archiver.archive.pb.GetTransactionRequest - 14, // 16: qubic.archiver.archive.pb.ArchiveService.GetQuorumTickData:input_type -> qubic.archiver.archive.pb.GetQuorumTickDataRequest - 17, // 17: qubic.archiver.archive.pb.ArchiveService.GetComputors:input_type -> qubic.archiver.archive.pb.GetComputorsRequest - 20, // 18: qubic.archiver.archive.pb.ArchiveService.GetIdentityInfo:input_type -> qubic.archiver.archive.pb.GetIdentityInfoRequest - 22, // 19: qubic.archiver.archive.pb.ArchiveService.GetLastProcessedTick:input_type -> qubic.archiver.archive.pb.GetLastProcessedTickRequest - 24, // 20: qubic.archiver.archive.pb.ArchiveService.SendRawTransaction:input_type -> qubic.archiver.archive.pb.SendRawTransactionRequest - 26, // 21: qubic.archiver.archive.pb.ArchiveService.GetSkippedTicks:input_type -> qubic.archiver.archive.pb.GetSkippedTicksRequest - 2, // 22: qubic.archiver.archive.pb.ArchiveService.GetTickData:output_type -> qubic.archiver.archive.pb.GetTickDataResponse - 8, // 23: qubic.archiver.archive.pb.ArchiveService.GetTickTransactions:output_type -> qubic.archiver.archive.pb.GetTickTransactionsResponse - 5, // 24: qubic.archiver.archive.pb.ArchiveService.GetTransaction:output_type -> qubic.archiver.archive.pb.GetTransactionResponse - 15, // 25: qubic.archiver.archive.pb.ArchiveService.GetQuorumTickData:output_type -> qubic.archiver.archive.pb.GetQuorumTickDataResponse - 18, // 26: qubic.archiver.archive.pb.ArchiveService.GetComputors:output_type -> qubic.archiver.archive.pb.GetComputorsResponse - 21, // 27: qubic.archiver.archive.pb.ArchiveService.GetIdentityInfo:output_type -> qubic.archiver.archive.pb.GetIdentityInfoResponse - 23, // 28: qubic.archiver.archive.pb.ArchiveService.GetLastProcessedTick:output_type -> qubic.archiver.archive.pb.GetLastProcessedTickResponse - 25, // 29: qubic.archiver.archive.pb.ArchiveService.SendRawTransaction:output_type -> qubic.archiver.archive.pb.SendRawTransactionResponse - 27, // 30: qubic.archiver.archive.pb.ArchiveService.GetSkippedTicks:output_type -> qubic.archiver.archive.pb.GetSkippedTicksResponse - 22, // [22:31] is the sub-list for method output_type - 13, // [13:22] is the sub-list for method input_type - 13, // [13:13] is the sub-list for extension type_name - 13, // [13:13] is the sub-list for extension extendee - 0, // [0:13] is the sub-list for field type_name + 6, // 9: qubic.archiver.archive.pb.TransferTransactionsPerTick.transactions:type_name -> qubic.archiver.archive.pb.Transactions + 20, // 10: qubic.archiver.archive.pb.TransferTransactions.transfer_transactions_per_tick:type_name -> qubic.archiver.archive.pb.TransferTransactionsPerTick + 19, // 11: qubic.archiver.archive.pb.GetIdentityInfoResponse.identity_info:type_name -> qubic.archiver.archive.pb.IdentityInfo + 35, // 12: qubic.archiver.archive.pb.GetLastProcessedTickResponse.last_processed_ticks_per_epoch:type_name -> qubic.archiver.archive.pb.GetLastProcessedTickResponse.LastProcessedTicksPerEpochEntry + 11, // 13: qubic.archiver.archive.pb.GetSkippedTicksResponse.skipped_ticks:type_name -> qubic.archiver.archive.pb.SkippedTicksInterval + 21, // 14: qubic.archiver.archive.pb.GetTransferTransactionsResponse.transfer_transactions:type_name -> qubic.archiver.archive.pb.TransferTransactions + 20, // 15: qubic.archiver.archive.pb.GetTransferTransactionsPerTickResponse.transfer_transactions_per_tick:type_name -> qubic.archiver.archive.pb.TransferTransactionsPerTick + 9, // 16: qubic.archiver.archive.pb.QuorumTickData.QuorumDiffPerComputorEntry.value:type_name -> qubic.archiver.archive.pb.QuorumDiff + 1, // 17: qubic.archiver.archive.pb.ArchiveService.GetTickData:input_type -> qubic.archiver.archive.pb.GetTickDataRequest + 7, // 18: qubic.archiver.archive.pb.ArchiveService.GetTickTransactions:input_type -> qubic.archiver.archive.pb.GetTickTransactionsRequest + 4, // 19: qubic.archiver.archive.pb.ArchiveService.GetTransaction:input_type -> qubic.archiver.archive.pb.GetTransactionRequest + 14, // 20: qubic.archiver.archive.pb.ArchiveService.GetQuorumTickData:input_type -> qubic.archiver.archive.pb.GetQuorumTickDataRequest + 17, // 21: qubic.archiver.archive.pb.ArchiveService.GetComputors:input_type -> qubic.archiver.archive.pb.GetComputorsRequest + 22, // 22: qubic.archiver.archive.pb.ArchiveService.GetIdentityInfo:input_type -> qubic.archiver.archive.pb.GetIdentityInfoRequest + 24, // 23: qubic.archiver.archive.pb.ArchiveService.GetLastProcessedTick:input_type -> qubic.archiver.archive.pb.GetLastProcessedTickRequest + 26, // 24: qubic.archiver.archive.pb.ArchiveService.SendRawTransaction:input_type -> qubic.archiver.archive.pb.SendRawTransactionRequest + 28, // 25: qubic.archiver.archive.pb.ArchiveService.GetSkippedTicks:input_type -> qubic.archiver.archive.pb.GetSkippedTicksRequest + 30, // 26: qubic.archiver.archive.pb.ArchiveService.GetTransferTransactions:input_type -> qubic.archiver.archive.pb.GetTransferTransactionsRequest + 32, // 27: qubic.archiver.archive.pb.ArchiveService.GetTransferTransactionsPerTick:input_type -> qubic.archiver.archive.pb.GetTransferTransactionsPerTickRequest + 2, // 28: qubic.archiver.archive.pb.ArchiveService.GetTickData:output_type -> qubic.archiver.archive.pb.GetTickDataResponse + 8, // 29: qubic.archiver.archive.pb.ArchiveService.GetTickTransactions:output_type -> qubic.archiver.archive.pb.GetTickTransactionsResponse + 5, // 30: qubic.archiver.archive.pb.ArchiveService.GetTransaction:output_type -> qubic.archiver.archive.pb.GetTransactionResponse + 15, // 31: qubic.archiver.archive.pb.ArchiveService.GetQuorumTickData:output_type -> qubic.archiver.archive.pb.GetQuorumTickDataResponse + 18, // 32: qubic.archiver.archive.pb.ArchiveService.GetComputors:output_type -> qubic.archiver.archive.pb.GetComputorsResponse + 23, // 33: qubic.archiver.archive.pb.ArchiveService.GetIdentityInfo:output_type -> qubic.archiver.archive.pb.GetIdentityInfoResponse + 25, // 34: qubic.archiver.archive.pb.ArchiveService.GetLastProcessedTick:output_type -> qubic.archiver.archive.pb.GetLastProcessedTickResponse + 27, // 35: qubic.archiver.archive.pb.ArchiveService.SendRawTransaction:output_type -> qubic.archiver.archive.pb.SendRawTransactionResponse + 29, // 36: qubic.archiver.archive.pb.ArchiveService.GetSkippedTicks:output_type -> qubic.archiver.archive.pb.GetSkippedTicksResponse + 31, // 37: qubic.archiver.archive.pb.ArchiveService.GetTransferTransactions:output_type -> qubic.archiver.archive.pb.GetTransferTransactionsResponse + 33, // 38: qubic.archiver.archive.pb.ArchiveService.GetTransferTransactionsPerTick:output_type -> qubic.archiver.archive.pb.GetTransferTransactionsPerTickResponse + 28, // [28:39] is the sub-list for method output_type + 17, // [17:28] is the sub-list for method input_type + 17, // [17:17] is the sub-list for extension type_name + 17, // [17:17] is the sub-list for extension extendee + 0, // [0:17] is the sub-list for field type_name } func init() { file_archive_proto_init() } @@ -2333,7 +2713,7 @@ func file_archive_proto_init() { } } file_archive_proto_msgTypes[20].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GetIdentityInfoRequest); i { + switch v := v.(*TransferTransactionsPerTick); i { case 0: return &v.state case 1: @@ -2345,7 +2725,7 @@ func file_archive_proto_init() { } } file_archive_proto_msgTypes[21].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GetIdentityInfoResponse); i { + switch v := v.(*TransferTransactions); i { case 0: return &v.state case 1: @@ -2357,7 +2737,7 @@ func file_archive_proto_init() { } } file_archive_proto_msgTypes[22].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GetLastProcessedTickRequest); i { + switch v := v.(*GetIdentityInfoRequest); i { case 0: return &v.state case 1: @@ -2369,7 +2749,7 @@ func file_archive_proto_init() { } } file_archive_proto_msgTypes[23].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GetLastProcessedTickResponse); i { + switch v := v.(*GetIdentityInfoResponse); i { case 0: return &v.state case 1: @@ -2381,7 +2761,7 @@ func file_archive_proto_init() { } } file_archive_proto_msgTypes[24].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*SendRawTransactionRequest); i { + switch v := v.(*GetLastProcessedTickRequest); i { case 0: return &v.state case 1: @@ -2393,7 +2773,7 @@ func file_archive_proto_init() { } } file_archive_proto_msgTypes[25].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*SendRawTransactionResponse); i { + switch v := v.(*GetLastProcessedTickResponse); i { case 0: return &v.state case 1: @@ -2405,7 +2785,7 @@ func file_archive_proto_init() { } } file_archive_proto_msgTypes[26].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GetSkippedTicksRequest); i { + switch v := v.(*SendRawTransactionRequest); i { case 0: return &v.state case 1: @@ -2417,6 +2797,30 @@ func file_archive_proto_init() { } } file_archive_proto_msgTypes[27].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*SendRawTransactionResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_archive_proto_msgTypes[28].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetSkippedTicksRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_archive_proto_msgTypes[29].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*GetSkippedTicksResponse); i { case 0: return &v.state @@ -2428,6 +2832,54 @@ func file_archive_proto_init() { return nil } } + file_archive_proto_msgTypes[30].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetTransferTransactionsRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_archive_proto_msgTypes[31].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetTransferTransactionsResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_archive_proto_msgTypes[32].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetTransferTransactionsPerTickRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_archive_proto_msgTypes[33].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetTransferTransactionsPerTickResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } } type x struct{} out := protoimpl.TypeBuilder{ @@ -2435,7 +2887,7 @@ func file_archive_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_archive_proto_rawDesc, NumEnums: 0, - NumMessages: 30, + NumMessages: 36, NumExtensions: 0, NumServices: 1, }, diff --git a/protobuff/archive.pb.gw.go b/protobuff/archive.pb.gw.go index 5e1ec81..a982124 100644 --- a/protobuff/archive.pb.gw.go +++ b/protobuff/archive.pb.gw.go @@ -337,6 +337,74 @@ func local_request_ArchiveService_GetSkippedTicks_0(ctx context.Context, marshal } +func request_ArchiveService_GetTransferTransactions_0(ctx context.Context, marshaler runtime.Marshaler, client ArchiveServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq GetTransferTransactionsRequest + var metadata runtime.ServerMetadata + + newReader, berr := utilities.IOReaderFactory(req.Body) + if berr != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr) + } + if err := marshaler.NewDecoder(newReader()).Decode(&protoReq); err != nil && err != io.EOF { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := client.GetTransferTransactions(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_ArchiveService_GetTransferTransactions_0(ctx context.Context, marshaler runtime.Marshaler, server ArchiveServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq GetTransferTransactionsRequest + var metadata runtime.ServerMetadata + + newReader, berr := utilities.IOReaderFactory(req.Body) + if berr != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr) + } + if err := marshaler.NewDecoder(newReader()).Decode(&protoReq); err != nil && err != io.EOF { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := server.GetTransferTransactions(ctx, &protoReq) + return msg, metadata, err + +} + +func request_ArchiveService_GetTransferTransactionsPerTick_0(ctx context.Context, marshaler runtime.Marshaler, client ArchiveServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq GetTransferTransactionsPerTickRequest + var metadata runtime.ServerMetadata + + newReader, berr := utilities.IOReaderFactory(req.Body) + if berr != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr) + } + if err := marshaler.NewDecoder(newReader()).Decode(&protoReq); err != nil && err != io.EOF { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := client.GetTransferTransactionsPerTick(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_ArchiveService_GetTransferTransactionsPerTick_0(ctx context.Context, marshaler runtime.Marshaler, server ArchiveServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq GetTransferTransactionsPerTickRequest + var metadata runtime.ServerMetadata + + newReader, berr := utilities.IOReaderFactory(req.Body) + if berr != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr) + } + if err := marshaler.NewDecoder(newReader()).Decode(&protoReq); err != nil && err != io.EOF { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := server.GetTransferTransactionsPerTick(ctx, &protoReq) + return msg, metadata, err + +} + // RegisterArchiveServiceHandlerServer registers the http handlers for service ArchiveService to "mux". // UnaryRPC :call ArchiveServiceServer directly. // StreamingRPC :currently unsupported pending https://github.com/grpc/grpc-go/issues/906. @@ -568,6 +636,56 @@ func RegisterArchiveServiceHandlerServer(ctx context.Context, mux *runtime.Serve }) + mux.Handle("POST", pattern_ArchiveService_GetTransferTransactions_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/qubic.archiver.archive.pb.ArchiveService/GetTransferTransactions", runtime.WithHTTPPathPattern("/qubic.archiver.archive.pb.ArchiveService/GetTransferTransactions")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_ArchiveService_GetTransferTransactions_0(annotatedContext, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + + forward_ArchiveService_GetTransferTransactions_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("POST", pattern_ArchiveService_GetTransferTransactionsPerTick_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/qubic.archiver.archive.pb.ArchiveService/GetTransferTransactionsPerTick", runtime.WithHTTPPathPattern("/qubic.archiver.archive.pb.ArchiveService/GetTransferTransactionsPerTick")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_ArchiveService_GetTransferTransactionsPerTick_0(annotatedContext, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + + forward_ArchiveService_GetTransferTransactionsPerTick_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + return nil } @@ -807,6 +925,50 @@ func RegisterArchiveServiceHandlerClient(ctx context.Context, mux *runtime.Serve }) + mux.Handle("POST", pattern_ArchiveService_GetTransferTransactions_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/qubic.archiver.archive.pb.ArchiveService/GetTransferTransactions", runtime.WithHTTPPathPattern("/qubic.archiver.archive.pb.ArchiveService/GetTransferTransactions")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_ArchiveService_GetTransferTransactions_0(annotatedContext, inboundMarshaler, client, req, pathParams) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + + forward_ArchiveService_GetTransferTransactions_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("POST", pattern_ArchiveService_GetTransferTransactionsPerTick_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/qubic.archiver.archive.pb.ArchiveService/GetTransferTransactionsPerTick", runtime.WithHTTPPathPattern("/qubic.archiver.archive.pb.ArchiveService/GetTransferTransactionsPerTick")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_ArchiveService_GetTransferTransactionsPerTick_0(annotatedContext, inboundMarshaler, client, req, pathParams) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + + forward_ArchiveService_GetTransferTransactionsPerTick_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + return nil } @@ -828,6 +990,10 @@ var ( pattern_ArchiveService_SendRawTransaction_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1}, []string{"qubic.archiver.archive.pb.ArchiveService", "SendRawTransaction"}, "")) pattern_ArchiveService_GetSkippedTicks_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1}, []string{"qubic.archiver.archive.pb.ArchiveService", "GetSkippedTicks"}, "")) + + pattern_ArchiveService_GetTransferTransactions_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1}, []string{"qubic.archiver.archive.pb.ArchiveService", "GetTransferTransactions"}, "")) + + pattern_ArchiveService_GetTransferTransactionsPerTick_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1}, []string{"qubic.archiver.archive.pb.ArchiveService", "GetTransferTransactionsPerTick"}, "")) ) var ( @@ -848,4 +1014,8 @@ var ( forward_ArchiveService_SendRawTransaction_0 = runtime.ForwardResponseMessage forward_ArchiveService_GetSkippedTicks_0 = runtime.ForwardResponseMessage + + forward_ArchiveService_GetTransferTransactions_0 = runtime.ForwardResponseMessage + + forward_ArchiveService_GetTransferTransactionsPerTick_0 = runtime.ForwardResponseMessage ) diff --git a/protobuff/archive.proto b/protobuff/archive.proto index 9b7b100..402cad6 100644 --- a/protobuff/archive.proto +++ b/protobuff/archive.proto @@ -126,6 +126,15 @@ message IdentityInfo { repeated string siblings_hex = 10; } +message TransferTransactionsPerTick { + uint32 tick_number = 1; + Transactions transactions = 2; +} + +message TransferTransactions { + repeated TransferTransactionsPerTick transfer_transactions_per_tick = 1; +} + message GetIdentityInfoRequest { string identity = 1; } @@ -154,6 +163,23 @@ message GetSkippedTicksResponse { repeated SkippedTicksInterval skipped_ticks = 1; } +message GetTransferTransactionsRequest { + string identity = 1; +} + +message GetTransferTransactionsResponse { + TransferTransactions transfer_transactions = 1; +} + +message GetTransferTransactionsPerTickRequest { + string identity = 1; + uint32 tick_number = 2; +} + +message GetTransferTransactionsPerTickResponse { + TransferTransactionsPerTick transfer_transactions_per_tick = 1; +} + service ArchiveService { rpc GetTickData(GetTickDataRequest) returns (GetTickDataResponse); rpc GetTickTransactions(GetTickTransactionsRequest) returns (GetTickTransactionsResponse); @@ -164,4 +190,6 @@ service ArchiveService { rpc GetLastProcessedTick(GetLastProcessedTickRequest) returns (GetLastProcessedTickResponse); rpc SendRawTransaction(SendRawTransactionRequest) returns (SendRawTransactionResponse); rpc GetSkippedTicks(GetSkippedTicksRequest) returns (GetSkippedTicksResponse); + rpc GetTransferTransactions(GetTransferTransactionsRequest) returns (GetTransferTransactionsResponse); + rpc GetTransferTransactionsPerTick(GetTransferTransactionsPerTickRequest) returns (GetTransferTransactionsPerTickResponse); } \ No newline at end of file diff --git a/protobuff/archive_grpc.pb.go b/protobuff/archive_grpc.pb.go index 7cf69ca..3bf1103 100644 --- a/protobuff/archive_grpc.pb.go +++ b/protobuff/archive_grpc.pb.go @@ -19,15 +19,17 @@ import ( const _ = grpc.SupportPackageIsVersion7 const ( - ArchiveService_GetTickData_FullMethodName = "/qubic.archiver.archive.pb.ArchiveService/GetTickData" - ArchiveService_GetTickTransactions_FullMethodName = "/qubic.archiver.archive.pb.ArchiveService/GetTickTransactions" - ArchiveService_GetTransaction_FullMethodName = "/qubic.archiver.archive.pb.ArchiveService/GetTransaction" - ArchiveService_GetQuorumTickData_FullMethodName = "/qubic.archiver.archive.pb.ArchiveService/GetQuorumTickData" - ArchiveService_GetComputors_FullMethodName = "/qubic.archiver.archive.pb.ArchiveService/GetComputors" - ArchiveService_GetIdentityInfo_FullMethodName = "/qubic.archiver.archive.pb.ArchiveService/GetIdentityInfo" - ArchiveService_GetLastProcessedTick_FullMethodName = "/qubic.archiver.archive.pb.ArchiveService/GetLastProcessedTick" - ArchiveService_SendRawTransaction_FullMethodName = "/qubic.archiver.archive.pb.ArchiveService/SendRawTransaction" - ArchiveService_GetSkippedTicks_FullMethodName = "/qubic.archiver.archive.pb.ArchiveService/GetSkippedTicks" + ArchiveService_GetTickData_FullMethodName = "/qubic.archiver.archive.pb.ArchiveService/GetTickData" + ArchiveService_GetTickTransactions_FullMethodName = "/qubic.archiver.archive.pb.ArchiveService/GetTickTransactions" + ArchiveService_GetTransaction_FullMethodName = "/qubic.archiver.archive.pb.ArchiveService/GetTransaction" + ArchiveService_GetQuorumTickData_FullMethodName = "/qubic.archiver.archive.pb.ArchiveService/GetQuorumTickData" + ArchiveService_GetComputors_FullMethodName = "/qubic.archiver.archive.pb.ArchiveService/GetComputors" + ArchiveService_GetIdentityInfo_FullMethodName = "/qubic.archiver.archive.pb.ArchiveService/GetIdentityInfo" + ArchiveService_GetLastProcessedTick_FullMethodName = "/qubic.archiver.archive.pb.ArchiveService/GetLastProcessedTick" + ArchiveService_SendRawTransaction_FullMethodName = "/qubic.archiver.archive.pb.ArchiveService/SendRawTransaction" + ArchiveService_GetSkippedTicks_FullMethodName = "/qubic.archiver.archive.pb.ArchiveService/GetSkippedTicks" + ArchiveService_GetTransferTransactions_FullMethodName = "/qubic.archiver.archive.pb.ArchiveService/GetTransferTransactions" + ArchiveService_GetTransferTransactionsPerTick_FullMethodName = "/qubic.archiver.archive.pb.ArchiveService/GetTransferTransactionsPerTick" ) // ArchiveServiceClient is the client API for ArchiveService service. @@ -43,6 +45,8 @@ type ArchiveServiceClient interface { GetLastProcessedTick(ctx context.Context, in *GetLastProcessedTickRequest, opts ...grpc.CallOption) (*GetLastProcessedTickResponse, error) SendRawTransaction(ctx context.Context, in *SendRawTransactionRequest, opts ...grpc.CallOption) (*SendRawTransactionResponse, error) GetSkippedTicks(ctx context.Context, in *GetSkippedTicksRequest, opts ...grpc.CallOption) (*GetSkippedTicksResponse, error) + GetTransferTransactions(ctx context.Context, in *GetTransferTransactionsRequest, opts ...grpc.CallOption) (*GetTransferTransactionsResponse, error) + GetTransferTransactionsPerTick(ctx context.Context, in *GetTransferTransactionsPerTickRequest, opts ...grpc.CallOption) (*GetTransferTransactionsPerTickResponse, error) } type archiveServiceClient struct { @@ -134,6 +138,24 @@ func (c *archiveServiceClient) GetSkippedTicks(ctx context.Context, in *GetSkipp return out, nil } +func (c *archiveServiceClient) GetTransferTransactions(ctx context.Context, in *GetTransferTransactionsRequest, opts ...grpc.CallOption) (*GetTransferTransactionsResponse, error) { + out := new(GetTransferTransactionsResponse) + err := c.cc.Invoke(ctx, ArchiveService_GetTransferTransactions_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *archiveServiceClient) GetTransferTransactionsPerTick(ctx context.Context, in *GetTransferTransactionsPerTickRequest, opts ...grpc.CallOption) (*GetTransferTransactionsPerTickResponse, error) { + out := new(GetTransferTransactionsPerTickResponse) + err := c.cc.Invoke(ctx, ArchiveService_GetTransferTransactionsPerTick_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + // ArchiveServiceServer is the server API for ArchiveService service. // All implementations must embed UnimplementedArchiveServiceServer // for forward compatibility @@ -147,6 +169,8 @@ type ArchiveServiceServer interface { GetLastProcessedTick(context.Context, *GetLastProcessedTickRequest) (*GetLastProcessedTickResponse, error) SendRawTransaction(context.Context, *SendRawTransactionRequest) (*SendRawTransactionResponse, error) GetSkippedTicks(context.Context, *GetSkippedTicksRequest) (*GetSkippedTicksResponse, error) + GetTransferTransactions(context.Context, *GetTransferTransactionsRequest) (*GetTransferTransactionsResponse, error) + GetTransferTransactionsPerTick(context.Context, *GetTransferTransactionsPerTickRequest) (*GetTransferTransactionsPerTickResponse, error) mustEmbedUnimplementedArchiveServiceServer() } @@ -181,6 +205,12 @@ func (UnimplementedArchiveServiceServer) SendRawTransaction(context.Context, *Se func (UnimplementedArchiveServiceServer) GetSkippedTicks(context.Context, *GetSkippedTicksRequest) (*GetSkippedTicksResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method GetSkippedTicks not implemented") } +func (UnimplementedArchiveServiceServer) GetTransferTransactions(context.Context, *GetTransferTransactionsRequest) (*GetTransferTransactionsResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetTransferTransactions not implemented") +} +func (UnimplementedArchiveServiceServer) GetTransferTransactionsPerTick(context.Context, *GetTransferTransactionsPerTickRequest) (*GetTransferTransactionsPerTickResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetTransferTransactionsPerTick not implemented") +} func (UnimplementedArchiveServiceServer) mustEmbedUnimplementedArchiveServiceServer() {} // UnsafeArchiveServiceServer may be embedded to opt out of forward compatibility for this service. @@ -356,6 +386,42 @@ func _ArchiveService_GetSkippedTicks_Handler(srv interface{}, ctx context.Contex return interceptor(ctx, in, info, handler) } +func _ArchiveService_GetTransferTransactions_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GetTransferTransactionsRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ArchiveServiceServer).GetTransferTransactions(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: ArchiveService_GetTransferTransactions_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ArchiveServiceServer).GetTransferTransactions(ctx, req.(*GetTransferTransactionsRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _ArchiveService_GetTransferTransactionsPerTick_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GetTransferTransactionsPerTickRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ArchiveServiceServer).GetTransferTransactionsPerTick(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: ArchiveService_GetTransferTransactionsPerTick_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ArchiveServiceServer).GetTransferTransactionsPerTick(ctx, req.(*GetTransferTransactionsPerTickRequest)) + } + return interceptor(ctx, in, info, handler) +} + // ArchiveService_ServiceDesc is the grpc.ServiceDesc for ArchiveService service. // It's only intended for direct use with grpc.RegisterService, // and not to be introspected or modified (even as a copy) @@ -399,6 +465,14 @@ var ArchiveService_ServiceDesc = grpc.ServiceDesc{ MethodName: "GetSkippedTicks", Handler: _ArchiveService_GetSkippedTicks_Handler, }, + { + MethodName: "GetTransferTransactions", + Handler: _ArchiveService_GetTransferTransactions_Handler, + }, + { + MethodName: "GetTransferTransactionsPerTick", + Handler: _ArchiveService_GetTransferTransactionsPerTick_Handler, + }, }, Streams: []grpc.StreamDesc{}, Metadata: "archive.proto", diff --git a/rpc/rpc_server.go b/rpc/rpc_server.go index c14026f..e574f40 100644 --- a/rpc/rpc_server.go +++ b/rpc/rpc_server.go @@ -22,6 +22,8 @@ import ( "net/http" ) +var _ protobuff.ArchiveServiceServer = &Server{} + type Server struct { protobuff.UnimplementedArchiveServiceServer listenAddrGRPC string @@ -185,6 +187,26 @@ func (s *Server) GetSkippedTicks(ctx context.Context, req *protobuff.GetSkippedT return &protobuff.GetSkippedTicksResponse{SkippedTicks: ticks.SkippedTicks}, nil } +func (s *Server) GetTransferTransactions(ctx context.Context, req *protobuff.GetTransferTransactionsRequest) (*protobuff.GetTransferTransactionsResponse, error) { + txs, err := s.store.GetTransferTransactions(ctx, req.Identity) + if err != nil { + return nil, status.Errorf(codes.Internal, "getting transfer transactions: %v", err) + } + + return &protobuff.GetTransferTransactionsResponse{TransferTransactions: txs}, nil +} +func (s *Server) GetTransferTransactionsPerTick(ctx context.Context, req *protobuff.GetTransferTransactionsPerTickRequest) (*protobuff.GetTransferTransactionsPerTickResponse, error) { + txs, err := s.store.GetTransferTransactionsPerTick(ctx, req.Identity, uint64(req.TickNumber)) + if err != nil { + if errors.Cause(err) == store.ErrNotFound { + return nil, status.Errorf(codes.NotFound, "transfer transactions for specified identity, tick pair not found") + } + return nil, status.Errorf(codes.Internal, "getting transfer transactions: %v", err) + } + + return &protobuff.GetTransferTransactionsPerTickResponse{TransferTransactionsPerTick: txs}, nil +} + func (s *Server) Start() error { srv := grpc.NewServer( grpc.MaxRecvMsgSize(600*1024*1024), diff --git a/store/keys.go b/store/keys.go index dc990d6..a80fada 100644 --- a/store/keys.go +++ b/store/keys.go @@ -5,13 +5,14 @@ import ( ) const ( - TickData = 0x00 - QuorumData = 0x01 - ComputorList = 0x02 - Transaction = 0x03 - LastProcessedTick = 0x04 - LastProcessedTickPerEpoch = 0x05 - SkippedTicksInterval = 0x06 + TickData = 0x00 + QuorumData = 0x01 + ComputorList = 0x02 + Transaction = 0x03 + LastProcessedTick = 0x04 + LastProcessedTickPerEpoch = 0x05 + SkippedTicksInterval = 0x06 + IdentityTransferTransactions = 0x07 ) func tickDataKey(tickNumber uint64) []byte { @@ -56,3 +57,18 @@ func lastProcessedTickKeyPerEpoch(epochNumber uint32) []byte { func skippedTicksIntervalKey() []byte { return []byte{SkippedTicksInterval} } + +func identityTransferTransactionsPerTickKey(identity string, tickNumber uint64) []byte { + key := []byte{IdentityTransferTransactions} + key = append(key, []byte(identity)...) + key = binary.BigEndian.AppendUint64(key, tickNumber) + + return key +} + +func identityTransferTransactions(identity string) []byte { + key := []byte{IdentityTransferTransactions} + key = append(key, []byte(identity)...) + + return key +} diff --git a/store/store.go b/store/store.go index 3f501fc..2cf914e 100644 --- a/store/store.go +++ b/store/store.go @@ -12,6 +12,8 @@ import ( "strconv" ) +const maxTickNumber = ^uint64(0) + var ErrNotFound = errors.New("store resource not found") type PebbleStore struct { @@ -50,7 +52,7 @@ func (s *PebbleStore) SetTickData(ctx context.Context, tickNumber uint64, td *pr return errors.Wrap(err, "serializing td proto") } - err = s.db.Set(key, serialized, &pebble.WriteOptions{Sync: true}) + err = s.db.Set(key, serialized, pebble.Sync) if err != nil { return errors.Wrap(err, "setting tick data") } @@ -85,7 +87,7 @@ func (s *PebbleStore) SetQuorumTickData(ctx context.Context, tickNumber uint64, return errors.Wrap(err, "serializing qtd proto") } - err = s.db.Set(key, serialized, &pebble.WriteOptions{Sync: true}) + err = s.db.Set(key, serialized, pebble.Sync) if err != nil { return errors.Wrap(err, "setting quorum tick data") } @@ -122,7 +124,7 @@ func (s *PebbleStore) SetComputors(ctx context.Context, epoch uint32, computors return errors.Wrap(err, "serializing computors proto") } - err = s.db.Set(key, serialized, &pebble.WriteOptions{Sync: true}) + err = s.db.Set(key, serialized, pebble.Sync) if err != nil { return errors.Wrap(err, "setting computors") } @@ -130,7 +132,7 @@ func (s *PebbleStore) SetComputors(ctx context.Context, epoch uint32, computors return nil } -func (s *PebbleStore) SetTickTransactions(ctx context.Context, txs *protobuff.Transactions) error { +func (s *PebbleStore) SetTransactions(ctx context.Context, txs *protobuff.Transactions) error { batch := s.db.NewBatchWithSize(len(txs.GetTransactions())) defer batch.Close() @@ -255,8 +257,7 @@ func (s *PebbleStore) GetLastProcessedTick(ctx context.Context) (uint64, error) } func (s *PebbleStore) GetLastProcessedTicksPerEpoch(ctx context.Context) (map[uint32]uint64, error) { - maxUint64 := ^uint64(0) - upperBound := append([]byte{LastProcessedTickPerEpoch}, []byte(strconv.FormatUint(maxUint64, 10))...) + upperBound := append([]byte{LastProcessedTickPerEpoch}, []byte(strconv.FormatUint(maxTickNumber, 10))...) iter, err := s.db.NewIter(&pebble.IterOptions{ LowerBound: []byte{LastProcessedTickPerEpoch}, UpperBound: upperBound, @@ -302,7 +303,7 @@ func (s *PebbleStore) SetSkippedTicksInterval(ctx context.Context, skippedTick * return errors.Wrap(err, "serializing skipped tick proto") } - err = s.db.Set(key, serialized, &pebble.WriteOptions{Sync: true}) + err = s.db.Set(key, serialized, pebble.Sync) if err != nil { return errors.Wrap(err, "setting skipped tick interval") } @@ -329,3 +330,72 @@ func (s *PebbleStore) GetSkippedTicksInterval(ctx context.Context) (*protobuff.S return &stil, nil } + +func (s *PebbleStore) PutTransferTransactionsPerTick(ctx context.Context, identity string, tickNumber uint64, txs *protobuff.TransferTransactionsPerTick) error { + key := identityTransferTransactionsPerTickKey(identity, tickNumber) + + serialized, err := protojson.Marshal(txs) + if err != nil { + return errors.Wrap(err, "serializing tx proto") + } + + err = s.db.Set(key, serialized, pebble.Sync) + if err != nil { + return errors.Wrap(err, "setting transfer tx") + } + + return nil +} + +func (s *PebbleStore) GetTransferTransactions(ctx context.Context, identity string) (*protobuff.TransferTransactions, error) { + partialKey := identityTransferTransactions(identity) + upperBound := append(partialKey, []byte(strconv.FormatUint(maxTickNumber, 10))...) + iter, err := s.db.NewIter(&pebble.IterOptions{ + LowerBound: partialKey, + UpperBound: upperBound, + }) + if err != nil { + return nil, errors.Wrap(err, "creating iter") + } + defer iter.Close() + + transferTxs := make([]*protobuff.TransferTransactionsPerTick, 0) + + for iter.First(); iter.Valid(); iter.Next() { + value, err := iter.ValueAndErr() + if err != nil { + return nil, errors.Wrap(err, "getting value from iter") + } + + var perTick protobuff.TransferTransactionsPerTick + + err = protojson.Unmarshal(value, &perTick) + if err != nil { + return nil, errors.Wrap(err, "unmarshalling transfer tx per tick to protobuff type") + } + + transferTxs = append(transferTxs, &perTick) + } + + return &protobuff.TransferTransactions{TransferTransactionsPerTick: transferTxs}, nil +} + +func (s *PebbleStore) GetTransferTransactionsPerTick(ctx context.Context, identity string, tickNumber uint64) (*protobuff.TransferTransactionsPerTick, error) { + key := identityTransferTransactionsPerTickKey(identity, tickNumber) + value, closer, err := s.db.Get(key) + if err != nil { + if errors.Is(err, pebble.ErrNotFound) { + return nil, ErrNotFound + } + + return nil, errors.Wrap(err, "getting transfer tx per tick") + } + defer closer.Close() + + var perTick protobuff.TransferTransactionsPerTick + if err := protojson.Unmarshal(value, &perTick); err != nil { + return nil, errors.Wrap(err, "unmarshalling transfer tx per tick to protobuff type") + } + + return &perTick, nil +} diff --git a/store/store_test.go b/store/store_test.go index 0634b1f..358aae2 100644 --- a/store/store_test.go +++ b/store/store_test.go @@ -4,13 +4,13 @@ import ( "context" "github.com/google/go-cmp/cmp" "github.com/google/go-cmp/cmp/cmpopts" + "github.com/stretchr/testify/require" "google.golang.org/protobuf/proto" "os" "path/filepath" "testing" "github.com/cockroachdb/pebble" - "github.com/stretchr/testify/assert" "go.uber.org/zap" pb "github.com/qubic/go-archiver/protobuff" // Update the import path to your generated protobuf package @@ -20,11 +20,11 @@ func TestPebbleStore_TickData(t *testing.T) { ctx := context.Background() // Setup test environment dbDir, err := os.MkdirTemp("", "pebble_test") - assert.NoError(t, err) + require.NoError(t, err) defer os.RemoveAll(dbDir) db, err := pebble.Open(filepath.Join(dbDir, "testdb"), &pebble.Options{}) - assert.NoError(t, err) + require.NoError(t, err) defer db.Close() logger, _ := zap.NewDevelopment() @@ -58,21 +58,21 @@ func TestPebbleStore_TickData(t *testing.T) { // Insert TickData records for _, td := range tickDatas { err = store.SetTickData(ctx, uint64(td.TickNumber), td) - assert.NoError(t, err, "Failed to store TickData") + require.NoError(t, err, "Failed to store TickData") } // Retrieve and verify each TickData record for _, tdOriginal := range tickDatas { retrievedTickData, err := store.GetTickData(ctx, uint64(tdOriginal.TickNumber)) - assert.NoError(t, err, "Failed to retrieve TickData") + require.NoError(t, err, "Failed to retrieve TickData") ok := proto.Equal(tdOriginal, retrievedTickData) - assert.Equal(t, true, ok, "Retrieved TickData does not match original") + require.Equal(t, true, ok, "Retrieved TickData does not match original") } // Test error handling for non-existent TickData _, err = store.GetTickData(ctx, 999) // Assuming 999 is a tick number that wasn't stored - assert.Error(t, err, "Expected an error for non-existent TickData") - assert.Equal(t, ErrNotFound, err, "Expected ErrNotFound for non-existent TickData") + require.Error(t, err, "Expected an error for non-existent TickData") + require.Equal(t, ErrNotFound, err, "Expected ErrNotFound for non-existent TickData") } func TestPebbleStore_QuorumTickData(t *testing.T) { @@ -80,11 +80,11 @@ func TestPebbleStore_QuorumTickData(t *testing.T) { // Setup test environment dbDir, err := os.MkdirTemp("", "pebble_test") - assert.NoError(t, err) + require.NoError(t, err) defer os.RemoveAll(dbDir) db, err := pebble.Open(filepath.Join(dbDir, "testdb"), &pebble.Options{}) - assert.NoError(t, err) + require.NoError(t, err) defer db.Close() logger, _ := zap.NewDevelopment() @@ -122,11 +122,11 @@ func TestPebbleStore_QuorumTickData(t *testing.T) { // Set QuorumTickData err = store.SetQuorumTickData(ctx, uint64(quorumData.QuorumTickStructure.TickNumber), quorumData) - assert.NoError(t, err) + require.NoError(t, err) // Get QuorumTickData retrievedData, err := store.GetQuorumTickData(ctx, uint64(quorumData.QuorumTickStructure.TickNumber)) - assert.NoError(t, err) + require.NoError(t, err) if diff := cmp.Diff(quorumData, retrievedData, cmpopts.IgnoreUnexported(pb.QuorumTickData{}, pb.QuorumTickStructure{}, pb.QuorumDiff{})); diff != "" { t.Fatalf("Unexpected result: %v", diff) @@ -134,8 +134,8 @@ func TestPebbleStore_QuorumTickData(t *testing.T) { // Test retrieval of non-existent QuorumTickData _, err = store.GetQuorumTickData(ctx, 999) // Assuming 999 is a tick number that wasn't stored - assert.Error(t, err) - assert.Equal(t, ErrNotFound, err) + require.Error(t, err) + require.Equal(t, ErrNotFound, err) } func TestPebbleStore_Computors(t *testing.T) { @@ -143,11 +143,11 @@ func TestPebbleStore_Computors(t *testing.T) { // Setup test environment dbDir, err := os.MkdirTemp("", "pebble_test") - assert.NoError(t, err) + require.NoError(t, err) defer os.RemoveAll(dbDir) db, err := pebble.Open(filepath.Join(dbDir, "testdb"), &pebble.Options{}) - assert.NoError(t, err) + require.NoError(t, err) defer db.Close() logger, _ := zap.NewDevelopment() @@ -163,22 +163,22 @@ func TestPebbleStore_Computors(t *testing.T) { // Set Computors err = store.SetComputors(ctx, epoch, computors) - assert.NoError(t, err) + require.NoError(t, err) // Get Computors retrievedComputors, err := store.GetComputors(ctx, epoch) - assert.NoError(t, err) + require.NoError(t, err) // Validate retrieved data - assert.NotNil(t, retrievedComputors) - assert.Equal(t, computors.Epoch, retrievedComputors.Epoch) - assert.ElementsMatch(t, computors.Identities, retrievedComputors.Identities) - assert.Equal(t, computors.SignatureHex, retrievedComputors.SignatureHex) + require.NotNil(t, retrievedComputors) + require.Equal(t, computors.Epoch, retrievedComputors.Epoch) + require.ElementsMatch(t, computors.Identities, retrievedComputors.Identities) + require.Equal(t, computors.SignatureHex, retrievedComputors.SignatureHex) // Test retrieval of non-existent Computors _, err = store.GetComputors(ctx, 999) // Assuming 999 is an epoch number that wasn't stored - assert.Error(t, err) - assert.Equal(t, ErrNotFound, err) + require.Error(t, err) + require.Equal(t, ErrNotFound, err) } func TestPebbleStore_TickTransactions(t *testing.T) { @@ -186,11 +186,11 @@ func TestPebbleStore_TickTransactions(t *testing.T) { // Setup test environment dbDir, err := os.MkdirTemp("", "pebble_test") - assert.NoError(t, err) + require.NoError(t, err) defer os.RemoveAll(dbDir) db, err := pebble.Open(filepath.Join(dbDir, "testdb"), &pebble.Options{}) - assert.NoError(t, err) + require.NoError(t, err) defer db.Close() logger, _ := zap.NewDevelopment() @@ -233,32 +233,32 @@ func TestPebbleStore_TickTransactions(t *testing.T) { TransactionIds: []string{"ff01", "cd01"}, } err = store.SetTickData(ctx, uint64(tickData.TickNumber), &tickData) - assert.NoError(t, err, "Failed to store TickData") + require.NoError(t, err, "Failed to store TickData") // Sample Transactions for testing tickNumber := uint64(12795005) - // Assuming SetTickTransactions stores transactions for a tick - err = store.SetTickTransactions(ctx, transactions) - assert.NoError(t, err) + // Assuming SetTransactions stores transactions for a tick + err = store.SetTransactions(ctx, transactions) + require.NoError(t, err) // GetTickTransactions retrieves stored transactions for a tick retrievedTransactions, err := store.GetTickTransactions(ctx, tickNumber) - assert.NoError(t, err) - assert.NotNil(t, retrievedTransactions) + require.NoError(t, err) + require.NotNil(t, retrievedTransactions) // Validate the retrieved transactions - assert.Len(t, retrievedTransactions.Transactions, len(transactions.Transactions)) + require.Len(t, retrievedTransactions.Transactions, len(transactions.Transactions)) for i, tx := range transactions.Transactions { retrievedTx := retrievedTransactions.Transactions[i] - assert.Equal(t, tx.SourceId, retrievedTx.SourceId) + require.Equal(t, tx.SourceId, retrievedTx.SourceId) // Continue with other fields... } // Test retrieval for a non-existent tick _, err = store.GetTickTransactions(ctx, 999) // Assuming 999 is a tick number that wasn't stored - assert.Error(t, err) - assert.Equal(t, ErrNotFound, err) + require.Error(t, err) + require.Equal(t, ErrNotFound, err) } func TestPebbleStore_GetTransaction(t *testing.T) { @@ -266,11 +266,11 @@ func TestPebbleStore_GetTransaction(t *testing.T) { // Setup test environment dbDir, err := os.MkdirTemp("", "pebble_test") - assert.NoError(t, err) + require.NoError(t, err) defer os.RemoveAll(dbDir) db, err := pebble.Open(filepath.Join(dbDir, "testdb"), &pebble.Options{}) - assert.NoError(t, err) + require.NoError(t, err) defer db.Close() logger, _ := zap.NewDevelopment() @@ -294,27 +294,27 @@ func TestPebbleStore_GetTransaction(t *testing.T) { }, } - // Use SetTickTransactions to store the transactions - err = store.SetTickTransactions(ctx, transactions) - assert.NoError(t, err) + // Use SetTransactions to store the transactions + err = store.SetTransactions(ctx, transactions) + require.NoError(t, err) retrievedTransaction, err := store.GetTransaction(ctx, targetTransaction.TxId) - assert.NoError(t, err) - assert.NotNil(t, retrievedTransaction) + require.NoError(t, err) + require.NotNil(t, retrievedTransaction) // Validate the retrieved transaction - assert.Equal(t, targetTransaction.SourceId, retrievedTransaction.SourceId) - assert.Equal(t, targetTransaction.DestId, retrievedTransaction.DestId) - assert.Equal(t, targetTransaction.Amount, retrievedTransaction.Amount) - assert.Equal(t, targetTransaction.InputType, retrievedTransaction.InputType) - assert.Equal(t, targetTransaction.InputSize, retrievedTransaction.InputSize) - assert.Equal(t, targetTransaction.InputHex, retrievedTransaction.InputHex) - assert.Equal(t, targetTransaction.SignatureHex, retrievedTransaction.SignatureHex) + require.Equal(t, targetTransaction.SourceId, retrievedTransaction.SourceId) + require.Equal(t, targetTransaction.DestId, retrievedTransaction.DestId) + require.Equal(t, targetTransaction.Amount, retrievedTransaction.Amount) + require.Equal(t, targetTransaction.InputType, retrievedTransaction.InputType) + require.Equal(t, targetTransaction.InputSize, retrievedTransaction.InputSize) + require.Equal(t, targetTransaction.InputHex, retrievedTransaction.InputHex) + require.Equal(t, targetTransaction.SignatureHex, retrievedTransaction.SignatureHex) // Optionally, test retrieval of a non-existent transaction _, err = store.GetTransaction(ctx, "00") - assert.Error(t, err) - assert.Equal(t, ErrNotFound, err) + require.Error(t, err) + require.Equal(t, ErrNotFound, err) } func TestSetAndGetLastProcessedTicksPerEpoch(t *testing.T) { @@ -322,11 +322,11 @@ func TestSetAndGetLastProcessedTicksPerEpoch(t *testing.T) { // Setup test environment dbDir, err := os.MkdirTemp("", "pebble_test") - assert.NoError(t, err) + require.NoError(t, err) defer os.RemoveAll(dbDir) db, err := pebble.Open(filepath.Join(dbDir, "testdb"), &pebble.Options{}) - assert.NoError(t, err) + require.NoError(t, err) defer db.Close() logger, _ := zap.NewDevelopment() @@ -334,42 +334,42 @@ func TestSetAndGetLastProcessedTicksPerEpoch(t *testing.T) { // Set last processed ticks per epoch err = store.SetLastProcessedTick(ctx, 16, 1) - assert.NoError(t, err) + require.NoError(t, err) // Get last processed tick per epoch lastProcessedTick, err := store.GetLastProcessedTick(ctx) - assert.NoError(t, err) - assert.Equal(t, uint64(16), lastProcessedTick) + require.NoError(t, err) + require.Equal(t, uint64(16), lastProcessedTick) lastProcessedTicksPerEpoch, err := store.GetLastProcessedTicksPerEpoch(ctx) - assert.NoError(t, err) - assert.Equal(t, map[uint32]uint64{1: 16}, lastProcessedTicksPerEpoch) + require.NoError(t, err) + require.Equal(t, map[uint32]uint64{1: 16}, lastProcessedTicksPerEpoch) // Set last processed ticks per epoch err = store.SetLastProcessedTick(ctx, 17, 1) - assert.NoError(t, err) + require.NoError(t, err) // Get last processed tick per epoch lastProcessedTick, err = store.GetLastProcessedTick(ctx) - assert.NoError(t, err) - assert.Equal(t, uint64(17), lastProcessedTick) + require.NoError(t, err) + require.Equal(t, uint64(17), lastProcessedTick) lastProcessedTicksPerEpoch, err = store.GetLastProcessedTicksPerEpoch(ctx) - assert.NoError(t, err) - assert.Equal(t, map[uint32]uint64{1: 17}, lastProcessedTicksPerEpoch) + require.NoError(t, err) + require.Equal(t, map[uint32]uint64{1: 17}, lastProcessedTicksPerEpoch) // Set last processed ticks per epoch err = store.SetLastProcessedTick(ctx, 18, 2) - assert.NoError(t, err) + require.NoError(t, err) // Get last processed tick per epoch lastProcessedTick, err = store.GetLastProcessedTick(ctx) - assert.NoError(t, err) - assert.Equal(t, uint64(18), lastProcessedTick) + require.NoError(t, err) + require.Equal(t, uint64(18), lastProcessedTick) lastProcessedTicksPerEpoch, err = store.GetLastProcessedTicksPerEpoch(ctx) - assert.NoError(t, err) - assert.Equal(t, map[uint32]uint64{1: 17, 2: 18}, lastProcessedTicksPerEpoch) + require.NoError(t, err) + require.Equal(t, map[uint32]uint64{1: 17, 2: 18}, lastProcessedTicksPerEpoch) } func TestGetSetSkippedTicks(t *testing.T) { @@ -377,11 +377,11 @@ func TestGetSetSkippedTicks(t *testing.T) { // Setup test environment dbDir, err := os.MkdirTemp("", "pebble_test") - assert.NoError(t, err) + require.NoError(t, err) defer os.RemoveAll(dbDir) db, err := pebble.Open(filepath.Join(dbDir, "testdb"), &pebble.Options{}) - assert.NoError(t, err) + require.NoError(t, err) defer db.Close() logger, _ := zap.NewDevelopment() @@ -393,12 +393,12 @@ func TestGetSetSkippedTicks(t *testing.T) { } // Set skipped ticks err = store.SetSkippedTicksInterval(ctx, &skippedTicksIntervalOne) - assert.NoError(t, err) + require.NoError(t, err) expected := pb.SkippedTicksIntervalList{SkippedTicks: []*pb.SkippedTicksInterval{&skippedTicksIntervalOne}} // Get skipped ticks got, err := store.GetSkippedTicksInterval(ctx) - assert.NoError(t, err) + require.NoError(t, err) if diff := cmp.Diff(&expected, got, cmpopts.IgnoreUnexported(pb.SkippedTicksInterval{}, pb.SkippedTicksIntervalList{})); diff != "" { t.Fatalf("Unexpected result: %v", diff) } @@ -409,12 +409,135 @@ func TestGetSetSkippedTicks(t *testing.T) { } err = store.SetSkippedTicksInterval(ctx, &skippedTicksIntervalTwo) - assert.NoError(t, err) + require.NoError(t, err) expected.SkippedTicks = append(expected.SkippedTicks, &skippedTicksIntervalTwo) got, err = store.GetSkippedTicksInterval(ctx) - assert.NoError(t, err) + require.NoError(t, err) if diff := cmp.Diff(&expected, got, cmpopts.IgnoreUnexported(pb.SkippedTicksInterval{}, pb.SkippedTicksIntervalList{})); diff != "" { t.Fatalf("Unexpected result: %v", diff) } } + +func TestPebbleStore_TransferTransactions(t *testing.T) { + ctx := context.Background() + + // Setup test environment + dbDir, err := os.MkdirTemp("", "pebble_test") + require.NoError(t, err) + defer os.RemoveAll(dbDir) + + db, err := pebble.Open(filepath.Join(dbDir, "testdb"), &pebble.Options{}) + require.NoError(t, err) + defer db.Close() + + logger, _ := zap.NewDevelopment() + store := NewPebbleStore(db, logger) + + // Sample Transactions for testing + forTickOne := pb.TransferTransactionsPerTick{ + TickNumber: 12, + Transactions: &pb.Transactions{ + Transactions: []*pb.Transaction{ + { + SourceId: "aaaaa", + DestId: "bbbbb", + Amount: 15, + TickNumber: 12, + InputType: 87, + InputSize: 122, + InputHex: "dddd", + SignatureHex: "ffff", + TxId: "eeee", + }, + { + SourceId: "bbbbb", + DestId: "aaaaa", + Amount: 25, + TickNumber: 12, + InputType: 65, + InputSize: 24, + InputHex: "ffff", + SignatureHex: "dddd", + TxId: "cccc", + }, + }, + }, + } + + forTickTwo := pb.TransferTransactionsPerTick{ + TickNumber: 15, + Transactions: &pb.Transactions{ + Transactions: []*pb.Transaction{ + { + SourceId: "aaaaa", + DestId: "bbbbb", + Amount: 15, + TickNumber: 15, + InputType: 87, + InputSize: 122, + InputHex: "dddd", + SignatureHex: "ffff", + TxId: "eeee", + }, + { + SourceId: "bbbbb", + DestId: "aaaaa", + Amount: 25, + TickNumber: 15, + InputType: 65, + InputSize: 24, + InputHex: "ffff", + SignatureHex: "dddd", + TxId: "cccc", + }, + }, + }, + } + + idOne := "QJRRSSKMJRDKUDTYVNYGAMQPULKAMILQQYOWBEXUDEUWQUMNGDHQYLOAJMEB" + idTwo := "IXTSDANOXIVIWGNDCNZVWSAVAEPBGLGSQTLSVHHBWEGKSEKPRQGWIJJCTUZB" + idThree := "QJRRSSKMJRDKUDTYVNYGAMQPULKAMILQQYOWBEXUDEUWQUMNGDHQYLOAJMXB" + + err = store.PutTransferTransactionsPerTick(ctx, idOne, 12, &forTickOne) + require.NoError(t, err) + got, err := store.GetTransferTransactionsPerTick(ctx, idOne, 12) + require.NoError(t, err) + diff := cmp.Diff(&forTickOne, got, cmpopts.IgnoreUnexported(pb.TransferTransactionsPerTick{}, pb.Transaction{}, pb.Transactions{})) + require.Equal(t, "", diff, "comparing first TransferTransactionsPerTick for idOne, forTickOne") + + err = store.PutTransferTransactionsPerTick(ctx, idTwo, 15, &forTickTwo) + require.NoError(t, err) + got, err = store.GetTransferTransactionsPerTick(ctx, idTwo, 15) + require.NoError(t, err) + diff = cmp.Diff(&forTickTwo, got, cmpopts.IgnoreUnexported(pb.TransferTransactionsPerTick{}, pb.Transaction{}, pb.Transactions{})) + require.Equal(t, "", diff, "comparing TransferTransactionsPerTick for idTwo, forTickTwo") + + err = store.PutTransferTransactionsPerTick(ctx, idOne, 13, &forTickOne) + require.NoError(t, err) + got, err = store.GetTransferTransactionsPerTick(ctx, idOne, 13) + require.NoError(t, err) + diff = cmp.Diff(&forTickOne, got, cmpopts.IgnoreUnexported(pb.TransferTransactionsPerTick{}, pb.Transaction{}, pb.Transactions{})) + require.Equal(t, "", diff, "comparing second TransferTransactionsPerTick for idOne, forTickOne") + + perIdentityTx, err := store.GetTransferTransactions(ctx, idOne) + require.NoError(t, err) + require.Equal(t, 2, len(perIdentityTx.TransferTransactionsPerTick)) + + expected := pb.TransferTransactions{TransferTransactionsPerTick: []*pb.TransferTransactionsPerTick{&forTickOne, &forTickOne}} + require.NoError(t, err) + diff = cmp.Diff(&expected, perIdentityTx, cmpopts.IgnoreUnexported(pb.TransferTransactionsPerTick{}, pb.Transaction{}, pb.Transactions{}, pb.TransferTransactions{})) + require.Equal(t, "", diff, "comparing perIdentityTx") + + // not existing identity means no transfers + perIdentityTx, err = store.GetTransferTransactions(ctx, idThree) + require.NoError(t, err) + diff = cmp.Diff(&pb.TransferTransactions{ + TransferTransactionsPerTick: []*pb.TransferTransactionsPerTick{}, + }, perIdentityTx, cmpopts.IgnoreUnexported(pb.TransferTransactions{}, pb.TransferTransactionsPerTick{}, pb.Transaction{}, pb.Transactions{})) + require.Equal(t, "", diff, "comparison of perIdentityTx for idThree") + + // not existing tick means ErrNotFound + _, err = store.GetTransferTransactionsPerTick(ctx, idOne, 14) + require.EqualError(t, err, ErrNotFound.Error()) +} diff --git a/utils/utils.go b/utils/utils.go index 8e0b02b..c934807 100644 --- a/utils/utils.go +++ b/utils/utils.go @@ -12,6 +12,8 @@ import ( var debug = false +type SigVerifierFunc = func(ctx context.Context, pubkey [32]byte, digest [32]byte, sig [64]byte) error + func FourQSigVerify(ctx context.Context, pubkey [32]byte, digest [32]byte, sig [64]byte) error { pubKeyHex := hex.EncodeToString(pubkey[:]) digestHex := hex.EncodeToString(digest[:]) diff --git a/validator/computors/validator.go b/validator/computors/validator.go index 4f557be..1cd7fff 100644 --- a/validator/computors/validator.go +++ b/validator/computors/validator.go @@ -9,7 +9,7 @@ import ( "github.com/qubic/go-node-connector/types" ) -func Validate(ctx context.Context, computors types.Computors) error { +func Validate(ctx context.Context, sigVerifierFunc utils.SigVerifierFunc, computors types.Computors) error { arbitratorID := types.Identity(types.ArbitratorIdentity) arbitratorPubKey, err := arbitratorID.ToPubKey(false) if err != nil { @@ -21,7 +21,7 @@ func Validate(ctx context.Context, computors types.Computors) error { return errors.Wrap(err, "getting digest from computors") } - err = utils.FourQSigVerify(ctx, arbitratorPubKey, digest, computors.Signature) + err = sigVerifierFunc(ctx, arbitratorPubKey, digest, computors.Signature) if err != nil { return errors.Wrap(err, "verifying computors signature") } diff --git a/validator/quorum/validator.go b/validator/quorum/validator.go index 6f6c658..ea8e3a1 100644 --- a/validator/quorum/validator.go +++ b/validator/quorum/validator.go @@ -10,7 +10,7 @@ import ( ) // Validate validates the quorum votes and if success returns the aligned votes back -func Validate(ctx context.Context, quorumVotes types.QuorumVotes, computors types.Computors) (types.QuorumVotes, error) { +func Validate(ctx context.Context, sigVerifierFunc utils.SigVerifierFunc, quorumVotes types.QuorumVotes, computors types.Computors) (types.QuorumVotes, error) { if len(quorumVotes) < types.MinimumQuorumVotes { return nil, errors.New("not enough quorum votes") } @@ -26,7 +26,7 @@ func Validate(ctx context.Context, quorumVotes types.QuorumVotes, computors type } log.Printf("Proceed to validate total quorum sigs: %d\n", len(alignedVotes)) - err = quorumTickSigVerify(ctx, alignedVotes, computors) + err = quorumTickSigVerify(ctx, sigVerifierFunc, alignedVotes, computors) if err != nil { return nil, errors.Wrap(err, "quorum tick signature verification failed") } @@ -105,7 +105,7 @@ func getAlignedVotes(quorumVotes types.QuorumVotes) (types.QuorumVotes, error) { return alignedVotes, nil } -func quorumTickSigVerify(ctx context.Context, quorumVotes types.QuorumVotes, computors types.Computors) error { +func quorumTickSigVerify(ctx context.Context, sigVerifierFunc utils.SigVerifierFunc, quorumVotes types.QuorumVotes, computors types.Computors) error { var successVotes = 0 failedIndexes := make([]uint16, 0, 0) failedIdentites := make([]string, 0, 0) @@ -116,7 +116,7 @@ func quorumTickSigVerify(ctx context.Context, quorumVotes types.QuorumVotes, com return errors.Wrap(err, "getting digest from tick data") } computorPubKey := computors.PubKeys[quorumTickData.ComputorIndex] - if err := utils.FourQSigVerify(ctx, computorPubKey, digest, quorumTickData.Signature); err != nil { + if err := sigVerifierFunc(ctx, computorPubKey, digest, quorumTickData.Signature); err != nil { //return errors.Wrapf(err, "quorum tick signature verification failed for computor index: %d", quorumTickData.ComputorIndex) //log.Printf("Quorum tick signature verification failed for computor index: %d. Err: %s\n", quorumTickData.ComputorIndex, err.Error()) failedIndexes = append(failedIndexes, quorumTickData.ComputorIndex) diff --git a/validator/quorum/validator_test.go b/validator/quorum/validator_test.go index dfdabb3..ab2ed76 100644 --- a/validator/quorum/validator_test.go +++ b/validator/quorum/validator_test.go @@ -7,6 +7,10 @@ import ( "testing" ) +var mockSigVerifierFunc = func(ctx context.Context, pubkey [32]byte, digest [32]byte, sig [64]byte) error { + return nil +} + // Sufficient quorum votes. // Insufficient quorum votes. // Mismatched votes in various fields. @@ -61,7 +65,7 @@ func TestValidateVotes(t *testing.T) { }, } - _, err := Validate(context.Background(), originalData, types.Computors{}) + _, err := Validate(context.Background(), mockSigVerifierFunc, originalData, types.Computors{}) require.ErrorContains(t, err, "not enough quorum votes") cases := []struct { diff --git a/validator/tick/validator.go b/validator/tick/validator.go index 90c9527..71e90d1 100644 --- a/validator/tick/validator.go +++ b/validator/tick/validator.go @@ -9,7 +9,7 @@ import ( "github.com/qubic/go-node-connector/types" ) -func Validate(ctx context.Context, data types.TickData, quorumTickVote types.QuorumTickVote, comps types.Computors) error { +func Validate(ctx context.Context, sigVerifierFunc utils.SigVerifierFunc, data types.TickData, quorumTickVote types.QuorumTickVote, comps types.Computors) error { //empty tick with empty quorum tx digest means other verification is not needed if (data.IsEmpty()) && quorumTickVote.TxDigest == [32]byte{} { return nil @@ -23,7 +23,7 @@ func Validate(ctx context.Context, data types.TickData, quorumTickVote types.Quo } // verify tick signature - err = utils.FourQSigVerify(ctx, computorPubKey, digest, data.Signature) + err = sigVerifierFunc(ctx, computorPubKey, digest, data.Signature) if err != nil { return errors.Wrap(err, "verifying tick signature") } diff --git a/validator/tx/validator.go b/validator/tx/validator.go index 4b29b46..8c1c72d 100644 --- a/validator/tx/validator.go +++ b/validator/tx/validator.go @@ -4,6 +4,7 @@ import ( "context" "encoding/hex" "github.com/pkg/errors" + "github.com/qubic/go-archiver/protobuff" "github.com/qubic/go-archiver/store" "github.com/qubic/go-archiver/utils" "github.com/qubic/go-node-connector/types" @@ -12,13 +13,13 @@ import ( var emptyTxDigest [32]byte -func Validate(ctx context.Context, transactions []types.Transaction, tickData types.TickData) ([]types.Transaction, error) { +func Validate(ctx context.Context, sigVerifierFunc utils.SigVerifierFunc, transactions []types.Transaction, tickData types.TickData) ([]types.Transaction, error) { digestsMap := createTxDigestsMap(tickData) //if len(transactions) != len(digestsMap) { // return nil, errors.Errorf("tx count mismatch. tx count: %d, digests count: %d", len(transactions), len(digestsMap)) //} - validTxs, err := validateTransactions(ctx, transactions, digestsMap) + validTxs, err := validateTransactions(ctx, sigVerifierFunc, transactions, digestsMap) if err != nil { return nil, errors.Wrap(err, "validating transactions") } @@ -26,7 +27,7 @@ func Validate(ctx context.Context, transactions []types.Transaction, tickData ty return validTxs, nil } -func validateTransactions(ctx context.Context, transactions []types.Transaction, digestsMap map[string]struct{}) ([]types.Transaction, error) { +func validateTransactions(ctx context.Context, sigVerifierFunc utils.SigVerifierFunc, transactions []types.Transaction, digestsMap map[string]struct{}) ([]types.Transaction, error) { validTransactions := make([]types.Transaction, 0, len(transactions)) for _, tx := range transactions { txDigest, err := getDigestFromTransaction(tx) @@ -50,7 +51,7 @@ func validateTransactions(ctx context.Context, transactions []types.Transaction, return nil, errors.Wrap(err, "constructing digest from tx data") } - err = utils.FourQSigVerify(ctx, tx.SourcePublicKey, constructedDigest, tx.Signature) + err = sigVerifierFunc(ctx, tx.SourcePublicKey, constructedDigest, tx.Signature) if err != nil { return nil, errors.Wrap(err, "verifying tx signature") } @@ -91,16 +92,92 @@ func createTxDigestsMap(tickData types.TickData) map[string]struct{} { return digestsMap } -func Store(ctx context.Context, store *store.PebbleStore, transactions types.Transactions) error { +func Store(ctx context.Context, store *store.PebbleStore, tickNumber uint64, transactions types.Transactions) error { + err := storeTickTransactions(ctx, store, transactions) + if err != nil { + return errors.Wrap(err, "storing tick transactions") + } + + err = storeTransferTransactions(ctx, store, tickNumber, transactions) + if err != nil { + return errors.Wrap(err, "storing transfer transactions") + } + + return nil +} + +func storeTickTransactions(ctx context.Context, store *store.PebbleStore, transactions types.Transactions) error { protoModel, err := qubicToProto(transactions) if err != nil { return errors.Wrap(err, "converting to proto") } - err = store.SetTickTransactions(ctx, protoModel) + err = store.SetTransactions(ctx, protoModel) if err != nil { return errors.Wrap(err, "storing tick transactions") } return nil } + +func storeTransferTransactions(ctx context.Context, store *store.PebbleStore, tickNumber uint64, transactions types.Transactions) error { + transferTransactions, err := removeNonTransferTransactionsAndConvert(transactions) + if err != nil { + return errors.Wrap(err, "removing non transfer transactions") + } + txsPerIdentity, err := createTransferTransactionsIdentityMap(ctx, transferTransactions) + if err != nil { + return errors.Wrap(err, "filtering transfer transactions") + } + + for id, txs := range txsPerIdentity { + err = store.PutTransferTransactionsPerTick(ctx, id, tickNumber, &protobuff.TransferTransactionsPerTick{TickNumber: uint32(tickNumber), Transactions: txs}) + if err != nil { + return errors.Wrap(err, "storing transfer transactions") + } + } + + return nil +} + +func removeNonTransferTransactionsAndConvert(transactions []types.Transaction) (*protobuff.Transactions, error) { + transferTransactions := make([]*protobuff.Transaction, 0) + for _, tx := range transactions { + if tx.Amount == 0 { + continue + } + + protoTx, err := txToProto(tx) + if err != nil { + return nil, errors.Wrap(err, "converting to proto") + } + + transferTransactions = append(transferTransactions, protoTx) + } + + return &protobuff.Transactions{Transactions: transferTransactions}, nil +} + +func createTransferTransactionsIdentityMap(ctx context.Context, txs *protobuff.Transactions) (map[string]*protobuff.Transactions, error) { + txsPerIdentity := make(map[string]*protobuff.Transactions) + for _, tx := range txs.Transactions { + _, ok := txsPerIdentity[tx.DestId] + if !ok { + txsPerIdentity[tx.DestId] = &protobuff.Transactions{ + Transactions: make([]*protobuff.Transaction, 0), + } + } + + _, ok = txsPerIdentity[tx.SourceId] + if !ok { + txsPerIdentity[tx.SourceId] = &protobuff.Transactions{ + Transactions: make([]*protobuff.Transaction, 0), + } + } + + txsPerIdentity[tx.DestId].Transactions = append(txsPerIdentity[tx.DestId].Transactions, tx) + txsPerIdentity[tx.SourceId].Transactions = append(txsPerIdentity[tx.SourceId].Transactions, tx) + } + + return txsPerIdentity, nil +} diff --git a/validator/tx/validator_test.go b/validator/tx/validator_test.go new file mode 100644 index 0000000..aa05f8e --- /dev/null +++ b/validator/tx/validator_test.go @@ -0,0 +1,232 @@ +package tx + +import ( + "context" + "github.com/cockroachdb/pebble" + "github.com/google/go-cmp/cmp" + "github.com/google/go-cmp/cmp/cmpopts" + "github.com/qubic/go-archiver/protobuff" + "github.com/qubic/go-archiver/store" + "github.com/qubic/go-node-connector/types" + "github.com/stretchr/testify/require" + "go.uber.org/zap" + "os" + "path/filepath" + "testing" +) + +func Test_CreateTransferTransactionsIdentityMap(t *testing.T) { + txs := protobuff.Transactions{ + Transactions: []*protobuff.Transaction{ + { + SourceId: "QJRRSSKMJRDKUDTYVNYGAMQPULKAMILQQYOWBEXUDEUWQUMNGDHQYLOAJMEB", + DestId: "IXTSDANOXIVIWGNDCNZVWSAVAEPBGLGSQTLSVHHBWEGKSEKPRQGWIJJCTUZB", + }, + { + SourceId: "IXTSDANOXIVIWGNDCNZVWSAVAEPBGLGSQTLSVHHBWEGKSEKPRQGWIJJCTUZB", + DestId: "QJRRSSKMJRDKUDTYVNYGAMQPULKAMILQQYOWBEXUDEUWQUMNGDHQYLOAJMEB", + }, + { + SourceId: "AXTSDANOXIVIWGNDCNZVWSAVAEPBGLGSQTLSVHHBWEGKSEKPRQGWIJJCTUZB", + DestId: "BJRRSSKMJRDKUDTYVNYGAMQPULKAMILQQYOWBEXUDEUWQUMNGDHQYLOAJMEB", + }, + { + SourceId: "QJRRSSKMJRDKUDTYVNYGAMQPULKAMILQQYOWBEXUDEUWQUMNGDHQYLOAJMEB", + DestId: "ZXTSDANOXIVIWGNDCNZVWSAVAEPBGLGSQTLSVHHBWEGKSEKPRQGWIJJCTUZB", + }, + }, + } + + expected := map[string]*protobuff.Transactions{ + "QJRRSSKMJRDKUDTYVNYGAMQPULKAMILQQYOWBEXUDEUWQUMNGDHQYLOAJMEB": { + Transactions: []*protobuff.Transaction{ + { + SourceId: "QJRRSSKMJRDKUDTYVNYGAMQPULKAMILQQYOWBEXUDEUWQUMNGDHQYLOAJMEB", + DestId: "IXTSDANOXIVIWGNDCNZVWSAVAEPBGLGSQTLSVHHBWEGKSEKPRQGWIJJCTUZB", + }, + { + SourceId: "IXTSDANOXIVIWGNDCNZVWSAVAEPBGLGSQTLSVHHBWEGKSEKPRQGWIJJCTUZB", + DestId: "QJRRSSKMJRDKUDTYVNYGAMQPULKAMILQQYOWBEXUDEUWQUMNGDHQYLOAJMEB", + }, + { + SourceId: "QJRRSSKMJRDKUDTYVNYGAMQPULKAMILQQYOWBEXUDEUWQUMNGDHQYLOAJMEB", + DestId: "ZXTSDANOXIVIWGNDCNZVWSAVAEPBGLGSQTLSVHHBWEGKSEKPRQGWIJJCTUZB", + }, + }, + }, + "IXTSDANOXIVIWGNDCNZVWSAVAEPBGLGSQTLSVHHBWEGKSEKPRQGWIJJCTUZB": { + Transactions: []*protobuff.Transaction{ + { + SourceId: "QJRRSSKMJRDKUDTYVNYGAMQPULKAMILQQYOWBEXUDEUWQUMNGDHQYLOAJMEB", + DestId: "IXTSDANOXIVIWGNDCNZVWSAVAEPBGLGSQTLSVHHBWEGKSEKPRQGWIJJCTUZB", + }, + { + SourceId: "IXTSDANOXIVIWGNDCNZVWSAVAEPBGLGSQTLSVHHBWEGKSEKPRQGWIJJCTUZB", + DestId: "QJRRSSKMJRDKUDTYVNYGAMQPULKAMILQQYOWBEXUDEUWQUMNGDHQYLOAJMEB", + }, + }, + }, + "AXTSDANOXIVIWGNDCNZVWSAVAEPBGLGSQTLSVHHBWEGKSEKPRQGWIJJCTUZB": { + Transactions: []*protobuff.Transaction{ + { + SourceId: "AXTSDANOXIVIWGNDCNZVWSAVAEPBGLGSQTLSVHHBWEGKSEKPRQGWIJJCTUZB", + DestId: "BJRRSSKMJRDKUDTYVNYGAMQPULKAMILQQYOWBEXUDEUWQUMNGDHQYLOAJMEB", + }, + }, + }, + "BJRRSSKMJRDKUDTYVNYGAMQPULKAMILQQYOWBEXUDEUWQUMNGDHQYLOAJMEB": { + Transactions: []*protobuff.Transaction{ + { + SourceId: "AXTSDANOXIVIWGNDCNZVWSAVAEPBGLGSQTLSVHHBWEGKSEKPRQGWIJJCTUZB", + DestId: "BJRRSSKMJRDKUDTYVNYGAMQPULKAMILQQYOWBEXUDEUWQUMNGDHQYLOAJMEB", + }, + }, + }, + "ZXTSDANOXIVIWGNDCNZVWSAVAEPBGLGSQTLSVHHBWEGKSEKPRQGWIJJCTUZB": { + Transactions: []*protobuff.Transaction{ + { + SourceId: "QJRRSSKMJRDKUDTYVNYGAMQPULKAMILQQYOWBEXUDEUWQUMNGDHQYLOAJMEB", + DestId: "ZXTSDANOXIVIWGNDCNZVWSAVAEPBGLGSQTLSVHHBWEGKSEKPRQGWIJJCTUZB", + }, + }, + }, + } + + got, err := createTransferTransactionsIdentityMap(context.Background(), &txs) + require.NoError(t, err) + diff := cmp.Diff(got, expected, cmpopts.IgnoreUnexported(protobuff.Transactions{}, protobuff.Transaction{})) + require.Empty(t, diff) +} + +func TestStore(t *testing.T) { + ctx := context.Background() + + // Setup test environment + dbDir, err := os.MkdirTemp("", "pebble_test") + require.NoError(t, err) + defer os.RemoveAll(dbDir) + + db, err := pebble.Open(filepath.Join(dbDir, "testdb"), &pebble.Options{}) + require.NoError(t, err) + defer db.Close() + + logger, _ := zap.NewDevelopment() + s := store.NewPebbleStore(db, logger) + + firstTick := []types.Transaction{ + { + SourcePublicKey: identityToPubkeyNoError("QJRRSSKMJRDKUDTYVNYGAMQPULKAMILQQYOWBEXUDEUWQUMNGDHQYLOAJMEB"), + DestinationPublicKey: identityToPubkeyNoError("IXTSDANOXIVIWGNDCNZVWSAVAEPBGLGSQTLSVHHBWEGKSEKPRQGWIJJCTUZB"), + Amount: 15, + }, + { + SourcePublicKey: identityToPubkeyNoError("IXTSDANOXIVIWGNDCNZVWSAVAEPBGLGSQTLSVHHBWEGKSEKPRQGWIJJCTUZB"), + DestinationPublicKey: identityToPubkeyNoError("QJRRSSKMJRDKUDTYVNYGAMQPULKAMILQQYOWBEXUDEUWQUMNGDHQYLOAJMEB"), + Amount: 20, + }, + } + + secondTick := []types.Transaction{ + { + SourcePublicKey: identityToPubkeyNoError("QJRRSSKMJRDKUDTYVNYGAMQPULKAMILQQYOWBEXUDEUWQUMNGDHQYLOAJMEB"), + DestinationPublicKey: identityToPubkeyNoError("IXTSDANOXIVIWGNDCNZVWSAVAEPBGLGSQTLSVHHBWEGKSEKPRQGWIJJCTUZB"), + Amount: 25, + }, + { + SourcePublicKey: identityToPubkeyNoError("IXTSDANOXIVIWGNDCNZVWSAVAEPBGLGSQTLSVHHBWEGKSEKPRQGWIJJCTUZB"), + DestinationPublicKey: identityToPubkeyNoError("QJRRSSKMJRDKUDTYVNYGAMQPULKAMILQQYOWBEXUDEUWQUMNGDHQYLOAJMEB"), + Amount: 30, + }, + + { + SourcePublicKey: identityToPubkeyNoError("IXTSDANOXIVIWGNDCNZVWSAVAEPBGLGSQTLSVHHBWEGKSEKPRQGWIJJCTUZB"), + DestinationPublicKey: identityToPubkeyNoError("QJRRSSKMJRDKUDTYVNYGAMQPULKAMILQQYOWBEXUDEUWQUMNGDHQYLOAJMEB"), + Amount: 0, + }, + { + SourcePublicKey: identityToPubkeyNoError("QJRRSSKMJRDKUDTYVNYGAMQPULKAMILQQYOWBEXUDEUWQUMNGDHQYLOAJMEB"), + DestinationPublicKey: identityToPubkeyNoError("IXTSDANOXIVIWGNDCNZVWSAVAEPBGLGSQTLSVHHBWEGKSEKPRQGWIJJCTUZB"), + Amount: 0, + }, + } + + err = Store(ctx, s, 1, firstTick) + require.NoError(t, err) + + expectedFirstTick := &protobuff.TransferTransactionsPerTick{ + TickNumber: 1, + Transactions: &protobuff.Transactions{Transactions: []*protobuff.Transaction{ + { + SourceId: "QJRRSSKMJRDKUDTYVNYGAMQPULKAMILQQYOWBEXUDEUWQUMNGDHQYLOAJMEB", + DestId: "IXTSDANOXIVIWGNDCNZVWSAVAEPBGLGSQTLSVHHBWEGKSEKPRQGWIJJCTUZB", + Amount: 15, + SignatureHex: "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + }, + { + SourceId: "IXTSDANOXIVIWGNDCNZVWSAVAEPBGLGSQTLSVHHBWEGKSEKPRQGWIJJCTUZB", + DestId: "QJRRSSKMJRDKUDTYVNYGAMQPULKAMILQQYOWBEXUDEUWQUMNGDHQYLOAJMEB", + Amount: 20, + SignatureHex: "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + }, + }}, + } + + got, err := s.GetTransferTransactionsPerTick(ctx, "QJRRSSKMJRDKUDTYVNYGAMQPULKAMILQQYOWBEXUDEUWQUMNGDHQYLOAJMEB", 1) + require.NoError(t, err) + diff := cmp.Diff(got, expectedFirstTick, cmpopts.IgnoreFields(protobuff.Transaction{}, "TxId"), cmpopts.IgnoreUnexported(protobuff.TransferTransactionsPerTick{}, protobuff.Transactions{}, protobuff.Transaction{})) + require.Empty(t, diff) + + got, err = s.GetTransferTransactionsPerTick(ctx, "IXTSDANOXIVIWGNDCNZVWSAVAEPBGLGSQTLSVHHBWEGKSEKPRQGWIJJCTUZB", 1) + require.NoError(t, err) + diff = cmp.Diff(got, expectedFirstTick, cmpopts.IgnoreFields(protobuff.Transaction{}, "TxId"), cmpopts.IgnoreUnexported(protobuff.TransferTransactionsPerTick{}, protobuff.Transactions{}, protobuff.Transaction{})) + require.Empty(t, diff) + + err = Store(ctx, s, 2, secondTick) + require.NoError(t, err) + + expectedSecondTick := &protobuff.TransferTransactionsPerTick{ + TickNumber: 2, + Transactions: &protobuff.Transactions{Transactions: []*protobuff.Transaction{ + { + SourceId: "QJRRSSKMJRDKUDTYVNYGAMQPULKAMILQQYOWBEXUDEUWQUMNGDHQYLOAJMEB", + DestId: "IXTSDANOXIVIWGNDCNZVWSAVAEPBGLGSQTLSVHHBWEGKSEKPRQGWIJJCTUZB", + Amount: 25, + SignatureHex: "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + }, + { + SourceId: "IXTSDANOXIVIWGNDCNZVWSAVAEPBGLGSQTLSVHHBWEGKSEKPRQGWIJJCTUZB", + DestId: "QJRRSSKMJRDKUDTYVNYGAMQPULKAMILQQYOWBEXUDEUWQUMNGDHQYLOAJMEB", + Amount: 30, + SignatureHex: "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + }, + }}, + } + + got, err = s.GetTransferTransactionsPerTick(ctx, "QJRRSSKMJRDKUDTYVNYGAMQPULKAMILQQYOWBEXUDEUWQUMNGDHQYLOAJMEB", 2) + require.NoError(t, err) + diff = cmp.Diff(got, expectedSecondTick, cmpopts.IgnoreFields(protobuff.Transaction{}, "TxId"), cmpopts.IgnoreUnexported(protobuff.TransferTransactionsPerTick{}, protobuff.Transactions{}, protobuff.Transaction{})) + require.Empty(t, diff) + + got, err = s.GetTransferTransactionsPerTick(ctx, "IXTSDANOXIVIWGNDCNZVWSAVAEPBGLGSQTLSVHHBWEGKSEKPRQGWIJJCTUZB", 2) + require.NoError(t, err) + diff = cmp.Diff(got, expectedSecondTick, cmpopts.IgnoreFields(protobuff.Transaction{}, "TxId"), cmpopts.IgnoreUnexported(protobuff.TransferTransactionsPerTick{}, protobuff.Transactions{}, protobuff.Transaction{})) + require.Empty(t, diff) + + expectedCombined := &protobuff.TransferTransactions{TransferTransactionsPerTick: []*protobuff.TransferTransactionsPerTick{expectedFirstTick, expectedSecondTick}} + gotCombined, err := s.GetTransferTransactions(ctx, "QJRRSSKMJRDKUDTYVNYGAMQPULKAMILQQYOWBEXUDEUWQUMNGDHQYLOAJMEB") + require.NoError(t, err) + diff = cmp.Diff(gotCombined, expectedCombined, cmpopts.IgnoreFields(protobuff.Transaction{}, "TxId"), cmpopts.IgnoreUnexported(protobuff.TransferTransactions{}, protobuff.TransferTransactionsPerTick{}, protobuff.Transactions{}, protobuff.Transaction{})) + require.Empty(t, diff) + + gotCombined, err = s.GetTransferTransactions(ctx, "IXTSDANOXIVIWGNDCNZVWSAVAEPBGLGSQTLSVHHBWEGKSEKPRQGWIJJCTUZB") + require.NoError(t, err) + diff = cmp.Diff(gotCombined, expectedCombined, cmpopts.IgnoreFields(protobuff.Transaction{}, "TxId"), cmpopts.IgnoreUnexported(protobuff.TransferTransactions{}, protobuff.TransferTransactionsPerTick{}, protobuff.Transactions{}, protobuff.Transaction{})) + require.Empty(t, diff) +} + +func identityToPubkeyNoError(id string) [32]byte { + identity := types.Identity(id) + pubKey, _ := identity.ToPubKey(false) + + return pubKey +} diff --git a/validator/validator.go b/validator/validator.go index 1c5325b..1846cc5 100644 --- a/validator/validator.go +++ b/validator/validator.go @@ -4,6 +4,7 @@ import ( "context" "github.com/pkg/errors" "github.com/qubic/go-archiver/store" + "github.com/qubic/go-archiver/utils" "github.com/qubic/go-archiver/validator/computors" "github.com/qubic/go-archiver/validator/quorum" "github.com/qubic/go-archiver/validator/tick" @@ -47,7 +48,7 @@ func (v *Validator) ValidateTick(ctx context.Context, tickNumber uint64) error { } } - err = computors.Validate(ctx, comps) + err = computors.Validate(ctx, utils.FourQSigVerify, comps) if err != nil { return errors.Wrap(err, "validating comps") } @@ -56,7 +57,7 @@ func (v *Validator) ValidateTick(ctx context.Context, tickNumber uint64) error { return errors.Wrap(err, "storing computors") } - alignedVotes, err := quorum.Validate(ctx, quorumVotes, comps) + alignedVotes, err := quorum.Validate(ctx, utils.FourQSigVerify, quorumVotes, comps) if err != nil { return errors.Wrap(err, "validating quorum") } @@ -75,7 +76,7 @@ func (v *Validator) ValidateTick(ctx context.Context, tickNumber uint64) error { } log.Println("Got tick data") - err = tick.Validate(ctx, tickData, alignedVotes[0], comps) + err = tick.Validate(ctx, utils.FourQSigVerify, tickData, alignedVotes[0], comps) if err != nil { return errors.Wrap(err, "validating tick data") } @@ -89,7 +90,7 @@ func (v *Validator) ValidateTick(ctx context.Context, tickNumber uint64) error { log.Printf("Validating %d transactions\n", len(transactions)) - validTxs, err := tx.Validate(ctx, transactions, tickData) + validTxs, err := tx.Validate(ctx, utils.FourQSigVerify, transactions, tickData) if err != nil { return errors.Wrap(err, "validating transactions") } @@ -111,7 +112,7 @@ func (v *Validator) ValidateTick(ctx context.Context, tickNumber uint64) error { log.Printf("Stored tick data\n") - err = tx.Store(ctx, v.store, validTxs) + err = tx.Store(ctx, v.store, tickNumber, validTxs) if err != nil { return errors.Wrap(err, "storing transactions") }