diff --git a/pkg/loop/internal/pb/contract_reader.pb.go b/pkg/loop/internal/pb/contract_reader.pb.go index 6d781f8ec..c3b30fe47 100644 --- a/pkg/loop/internal/pb/contract_reader.pb.go +++ b/pkg/loop/internal/pb/contract_reader.pb.go @@ -505,6 +505,125 @@ func (x *QueryKeyRequest) GetAsValueType() bool { return false } +// QueryKeysRequest has arguments for [github.com/smartcontractkit/chainlink-common/pkg/types.ContractReader.QueryKeys]. +type QueryKeysRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Filters []*ContractKeyFilter `protobuf:"bytes,1,rep,name=filters,proto3" json:"filters,omitempty"` + LimitAndSort *LimitAndSort `protobuf:"bytes,2,opt,name=limit_and_sort,json=limitAndSort,proto3" json:"limit_and_sort,omitempty"` +} + +func (x *QueryKeysRequest) Reset() { + *x = QueryKeysRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_contract_reader_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *QueryKeysRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*QueryKeysRequest) ProtoMessage() {} + +func (x *QueryKeysRequest) ProtoReflect() protoreflect.Message { + mi := &file_contract_reader_proto_msgTypes[3] + 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 QueryKeysRequest.ProtoReflect.Descriptor instead. +func (*QueryKeysRequest) Descriptor() ([]byte, []int) { + return file_contract_reader_proto_rawDescGZIP(), []int{3} +} + +func (x *QueryKeysRequest) GetFilters() []*ContractKeyFilter { + if x != nil { + return x.Filters + } + return nil +} + +func (x *QueryKeysRequest) GetLimitAndSort() *LimitAndSort { + if x != nil { + return x.LimitAndSort + } + return nil +} + +type ContractKeyFilter struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Contract *BoundContract `protobuf:"bytes,1,opt,name=contract,proto3" json:"contract,omitempty"` + Filter *QueryKeyFilter `protobuf:"bytes,2,opt,name=filter,proto3" json:"filter,omitempty"` + AsValueType bool `protobuf:"varint,4,opt,name=as_value_type,json=asValueType,proto3" json:"as_value_type,omitempty"` +} + +func (x *ContractKeyFilter) Reset() { + *x = ContractKeyFilter{} + if protoimpl.UnsafeEnabled { + mi := &file_contract_reader_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ContractKeyFilter) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ContractKeyFilter) ProtoMessage() {} + +func (x *ContractKeyFilter) ProtoReflect() protoreflect.Message { + mi := &file_contract_reader_proto_msgTypes[4] + 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 ContractKeyFilter.ProtoReflect.Descriptor instead. +func (*ContractKeyFilter) Descriptor() ([]byte, []int) { + return file_contract_reader_proto_rawDescGZIP(), []int{4} +} + +func (x *ContractKeyFilter) GetContract() *BoundContract { + if x != nil { + return x.Contract + } + return nil +} + +func (x *ContractKeyFilter) GetFilter() *QueryKeyFilter { + if x != nil { + return x.Filter + } + return nil +} + +func (x *ContractKeyFilter) GetAsValueType() bool { + if x != nil { + return x.AsValueType + } + return false +} + // BindRequest has arguments for [github.com/smartcontractkit/chainlink-common/pkg/types.ContractReader.Bind]. type BindRequest struct { state protoimpl.MessageState @@ -517,7 +636,7 @@ type BindRequest struct { func (x *BindRequest) Reset() { *x = BindRequest{} if protoimpl.UnsafeEnabled { - mi := &file_contract_reader_proto_msgTypes[3] + mi := &file_contract_reader_proto_msgTypes[5] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -530,7 +649,7 @@ func (x *BindRequest) String() string { func (*BindRequest) ProtoMessage() {} func (x *BindRequest) ProtoReflect() protoreflect.Message { - mi := &file_contract_reader_proto_msgTypes[3] + mi := &file_contract_reader_proto_msgTypes[5] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -543,7 +662,7 @@ func (x *BindRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use BindRequest.ProtoReflect.Descriptor instead. func (*BindRequest) Descriptor() ([]byte, []int) { - return file_contract_reader_proto_rawDescGZIP(), []int{3} + return file_contract_reader_proto_rawDescGZIP(), []int{5} } func (x *BindRequest) GetBindings() []*BoundContract { @@ -565,7 +684,7 @@ type UnbindRequest struct { func (x *UnbindRequest) Reset() { *x = UnbindRequest{} if protoimpl.UnsafeEnabled { - mi := &file_contract_reader_proto_msgTypes[4] + mi := &file_contract_reader_proto_msgTypes[6] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -578,7 +697,7 @@ func (x *UnbindRequest) String() string { func (*UnbindRequest) ProtoMessage() {} func (x *UnbindRequest) ProtoReflect() protoreflect.Message { - mi := &file_contract_reader_proto_msgTypes[4] + mi := &file_contract_reader_proto_msgTypes[6] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -591,7 +710,7 @@ func (x *UnbindRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use UnbindRequest.ProtoReflect.Descriptor instead. func (*UnbindRequest) Descriptor() ([]byte, []int) { - return file_contract_reader_proto_rawDescGZIP(), []int{4} + return file_contract_reader_proto_rawDescGZIP(), []int{6} } func (x *UnbindRequest) GetBindings() []*BoundContract { @@ -613,7 +732,7 @@ type GetLatestValueReply struct { func (x *GetLatestValueReply) Reset() { *x = GetLatestValueReply{} if protoimpl.UnsafeEnabled { - mi := &file_contract_reader_proto_msgTypes[5] + mi := &file_contract_reader_proto_msgTypes[7] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -626,7 +745,7 @@ func (x *GetLatestValueReply) String() string { func (*GetLatestValueReply) ProtoMessage() {} func (x *GetLatestValueReply) ProtoReflect() protoreflect.Message { - mi := &file_contract_reader_proto_msgTypes[5] + mi := &file_contract_reader_proto_msgTypes[7] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -639,7 +758,7 @@ func (x *GetLatestValueReply) ProtoReflect() protoreflect.Message { // Deprecated: Use GetLatestValueReply.ProtoReflect.Descriptor instead. func (*GetLatestValueReply) Descriptor() ([]byte, []int) { - return file_contract_reader_proto_rawDescGZIP(), []int{5} + return file_contract_reader_proto_rawDescGZIP(), []int{7} } func (x *GetLatestValueReply) GetRetVal() *VersionedBytes { @@ -662,7 +781,7 @@ type GetLatestValueWithHeadDataReply struct { func (x *GetLatestValueWithHeadDataReply) Reset() { *x = GetLatestValueWithHeadDataReply{} if protoimpl.UnsafeEnabled { - mi := &file_contract_reader_proto_msgTypes[6] + mi := &file_contract_reader_proto_msgTypes[8] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -675,7 +794,7 @@ func (x *GetLatestValueWithHeadDataReply) String() string { func (*GetLatestValueWithHeadDataReply) ProtoMessage() {} func (x *GetLatestValueWithHeadDataReply) ProtoReflect() protoreflect.Message { - mi := &file_contract_reader_proto_msgTypes[6] + mi := &file_contract_reader_proto_msgTypes[8] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -688,7 +807,7 @@ func (x *GetLatestValueWithHeadDataReply) ProtoReflect() protoreflect.Message { // Deprecated: Use GetLatestValueWithHeadDataReply.ProtoReflect.Descriptor instead. func (*GetLatestValueWithHeadDataReply) Descriptor() ([]byte, []int) { - return file_contract_reader_proto_rawDescGZIP(), []int{6} + return file_contract_reader_proto_rawDescGZIP(), []int{8} } func (x *GetLatestValueWithHeadDataReply) GetRetVal() *VersionedBytes { @@ -717,7 +836,7 @@ type BatchGetLatestValuesReply struct { func (x *BatchGetLatestValuesReply) Reset() { *x = BatchGetLatestValuesReply{} if protoimpl.UnsafeEnabled { - mi := &file_contract_reader_proto_msgTypes[7] + mi := &file_contract_reader_proto_msgTypes[9] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -730,7 +849,7 @@ func (x *BatchGetLatestValuesReply) String() string { func (*BatchGetLatestValuesReply) ProtoMessage() {} func (x *BatchGetLatestValuesReply) ProtoReflect() protoreflect.Message { - mi := &file_contract_reader_proto_msgTypes[7] + mi := &file_contract_reader_proto_msgTypes[9] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -743,7 +862,7 @@ func (x *BatchGetLatestValuesReply) ProtoReflect() protoreflect.Message { // Deprecated: Use BatchGetLatestValuesReply.ProtoReflect.Descriptor instead. func (*BatchGetLatestValuesReply) Descriptor() ([]byte, []int) { - return file_contract_reader_proto_rawDescGZIP(), []int{7} + return file_contract_reader_proto_rawDescGZIP(), []int{9} } func (x *BatchGetLatestValuesReply) GetResults() []*ContractBatchResult { @@ -765,7 +884,7 @@ type QueryKeyReply struct { func (x *QueryKeyReply) Reset() { *x = QueryKeyReply{} if protoimpl.UnsafeEnabled { - mi := &file_contract_reader_proto_msgTypes[8] + mi := &file_contract_reader_proto_msgTypes[10] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -778,7 +897,7 @@ func (x *QueryKeyReply) String() string { func (*QueryKeyReply) ProtoMessage() {} func (x *QueryKeyReply) ProtoReflect() protoreflect.Message { - mi := &file_contract_reader_proto_msgTypes[8] + mi := &file_contract_reader_proto_msgTypes[10] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -791,7 +910,7 @@ func (x *QueryKeyReply) ProtoReflect() protoreflect.Message { // Deprecated: Use QueryKeyReply.ProtoReflect.Descriptor instead. func (*QueryKeyReply) Descriptor() ([]byte, []int) { - return file_contract_reader_proto_rawDescGZIP(), []int{8} + return file_contract_reader_proto_rawDescGZIP(), []int{10} } func (x *QueryKeyReply) GetSequences() []*Sequence { @@ -801,6 +920,54 @@ func (x *QueryKeyReply) GetSequences() []*Sequence { return nil } +// QueryKeysReply has return arguments for [github.com/smartcontractkit/chainlink-common/pkg/types.ContractReader.QueryKeys]. +type QueryKeysReply struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Sequences []*SequenceWithKey `protobuf:"bytes,1,rep,name=sequences,proto3" json:"sequences,omitempty"` +} + +func (x *QueryKeysReply) Reset() { + *x = QueryKeysReply{} + if protoimpl.UnsafeEnabled { + mi := &file_contract_reader_proto_msgTypes[11] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *QueryKeysReply) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*QueryKeysReply) ProtoMessage() {} + +func (x *QueryKeysReply) ProtoReflect() protoreflect.Message { + mi := &file_contract_reader_proto_msgTypes[11] + 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 QueryKeysReply.ProtoReflect.Descriptor instead. +func (*QueryKeysReply) Descriptor() ([]byte, []int) { + return file_contract_reader_proto_rawDescGZIP(), []int{11} +} + +func (x *QueryKeysReply) GetSequences() []*SequenceWithKey { + if x != nil { + return x.Sequences + } + return nil +} + // ContractBatch is gRPC adapter for the BatchGetLatestValuesRequest struct map value [github.com/smartcontractkit/chainlink-common/pkg/types.ContractReader.BatchGetLatestValuesRequest]. type ContractBatch struct { state protoimpl.MessageState @@ -814,7 +981,7 @@ type ContractBatch struct { func (x *ContractBatch) Reset() { *x = ContractBatch{} if protoimpl.UnsafeEnabled { - mi := &file_contract_reader_proto_msgTypes[9] + mi := &file_contract_reader_proto_msgTypes[12] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -827,7 +994,7 @@ func (x *ContractBatch) String() string { func (*ContractBatch) ProtoMessage() {} func (x *ContractBatch) ProtoReflect() protoreflect.Message { - mi := &file_contract_reader_proto_msgTypes[9] + mi := &file_contract_reader_proto_msgTypes[12] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -840,7 +1007,7 @@ func (x *ContractBatch) ProtoReflect() protoreflect.Message { // Deprecated: Use ContractBatch.ProtoReflect.Descriptor instead. func (*ContractBatch) Descriptor() ([]byte, []int) { - return file_contract_reader_proto_rawDescGZIP(), []int{9} + return file_contract_reader_proto_rawDescGZIP(), []int{12} } func (x *ContractBatch) GetContract() *BoundContract { @@ -871,7 +1038,7 @@ type BatchRead struct { func (x *BatchRead) Reset() { *x = BatchRead{} if protoimpl.UnsafeEnabled { - mi := &file_contract_reader_proto_msgTypes[10] + mi := &file_contract_reader_proto_msgTypes[13] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -884,7 +1051,7 @@ func (x *BatchRead) String() string { func (*BatchRead) ProtoMessage() {} func (x *BatchRead) ProtoReflect() protoreflect.Message { - mi := &file_contract_reader_proto_msgTypes[10] + mi := &file_contract_reader_proto_msgTypes[13] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -897,7 +1064,7 @@ func (x *BatchRead) ProtoReflect() protoreflect.Message { // Deprecated: Use BatchRead.ProtoReflect.Descriptor instead. func (*BatchRead) Descriptor() ([]byte, []int) { - return file_contract_reader_proto_rawDescGZIP(), []int{10} + return file_contract_reader_proto_rawDescGZIP(), []int{13} } func (x *BatchRead) GetReadName() string { @@ -934,7 +1101,7 @@ type ContractBatchResult struct { func (x *ContractBatchResult) Reset() { *x = ContractBatchResult{} if protoimpl.UnsafeEnabled { - mi := &file_contract_reader_proto_msgTypes[11] + mi := &file_contract_reader_proto_msgTypes[14] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -947,7 +1114,7 @@ func (x *ContractBatchResult) String() string { func (*ContractBatchResult) ProtoMessage() {} func (x *ContractBatchResult) ProtoReflect() protoreflect.Message { - mi := &file_contract_reader_proto_msgTypes[11] + mi := &file_contract_reader_proto_msgTypes[14] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -960,7 +1127,7 @@ func (x *ContractBatchResult) ProtoReflect() protoreflect.Message { // Deprecated: Use ContractBatchResult.ProtoReflect.Descriptor instead. func (*ContractBatchResult) Descriptor() ([]byte, []int) { - return file_contract_reader_proto_rawDescGZIP(), []int{11} + return file_contract_reader_proto_rawDescGZIP(), []int{14} } func (x *ContractBatchResult) GetContract() *BoundContract { @@ -991,7 +1158,7 @@ type BatchReadResult struct { func (x *BatchReadResult) Reset() { *x = BatchReadResult{} if protoimpl.UnsafeEnabled { - mi := &file_contract_reader_proto_msgTypes[12] + mi := &file_contract_reader_proto_msgTypes[15] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1004,7 +1171,7 @@ func (x *BatchReadResult) String() string { func (*BatchReadResult) ProtoMessage() {} func (x *BatchReadResult) ProtoReflect() protoreflect.Message { - mi := &file_contract_reader_proto_msgTypes[12] + mi := &file_contract_reader_proto_msgTypes[15] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1017,7 +1184,7 @@ func (x *BatchReadResult) ProtoReflect() protoreflect.Message { // Deprecated: Use BatchReadResult.ProtoReflect.Descriptor instead. func (*BatchReadResult) Descriptor() ([]byte, []int) { - return file_contract_reader_proto_rawDescGZIP(), []int{12} + return file_contract_reader_proto_rawDescGZIP(), []int{15} } func (x *BatchReadResult) GetReadName() string { @@ -1055,7 +1222,7 @@ type Head struct { func (x *Head) Reset() { *x = Head{} if protoimpl.UnsafeEnabled { - mi := &file_contract_reader_proto_msgTypes[13] + mi := &file_contract_reader_proto_msgTypes[16] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1068,7 +1235,7 @@ func (x *Head) String() string { func (*Head) ProtoMessage() {} func (x *Head) ProtoReflect() protoreflect.Message { - mi := &file_contract_reader_proto_msgTypes[13] + mi := &file_contract_reader_proto_msgTypes[16] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1081,7 +1248,7 @@ func (x *Head) ProtoReflect() protoreflect.Message { // Deprecated: Use Head.ProtoReflect.Descriptor instead. func (*Head) Descriptor() ([]byte, []int) { - return file_contract_reader_proto_rawDescGZIP(), []int{13} + return file_contract_reader_proto_rawDescGZIP(), []int{16} } func (x *Head) GetHeight() string { @@ -1119,7 +1286,7 @@ type Sequence struct { func (x *Sequence) Reset() { *x = Sequence{} if protoimpl.UnsafeEnabled { - mi := &file_contract_reader_proto_msgTypes[14] + mi := &file_contract_reader_proto_msgTypes[17] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1132,7 +1299,7 @@ func (x *Sequence) String() string { func (*Sequence) ProtoMessage() {} func (x *Sequence) ProtoReflect() protoreflect.Message { - mi := &file_contract_reader_proto_msgTypes[14] + mi := &file_contract_reader_proto_msgTypes[17] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1145,7 +1312,7 @@ func (x *Sequence) ProtoReflect() protoreflect.Message { // Deprecated: Use Sequence.ProtoReflect.Descriptor instead. func (*Sequence) Descriptor() ([]byte, []int) { - return file_contract_reader_proto_rawDescGZIP(), []int{14} + return file_contract_reader_proto_rawDescGZIP(), []int{17} } func (x *Sequence) GetSequenceCursor() string { @@ -1169,6 +1336,77 @@ func (x *Sequence) GetData() *VersionedBytes { return nil } +type SequenceWithKey struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + SequenceCursor string `protobuf:"bytes,1,opt,name=sequence_cursor,json=sequenceCursor,proto3" json:"sequence_cursor,omitempty"` + Head *Head `protobuf:"bytes,2,opt,name=head,proto3" json:"head,omitempty"` + Data *VersionedBytes `protobuf:"bytes,3,opt,name=data,proto3" json:"data,omitempty"` + Key string `protobuf:"bytes,4,opt,name=key,proto3" json:"key,omitempty"` +} + +func (x *SequenceWithKey) Reset() { + *x = SequenceWithKey{} + if protoimpl.UnsafeEnabled { + mi := &file_contract_reader_proto_msgTypes[18] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *SequenceWithKey) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SequenceWithKey) ProtoMessage() {} + +func (x *SequenceWithKey) ProtoReflect() protoreflect.Message { + mi := &file_contract_reader_proto_msgTypes[18] + 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 SequenceWithKey.ProtoReflect.Descriptor instead. +func (*SequenceWithKey) Descriptor() ([]byte, []int) { + return file_contract_reader_proto_rawDescGZIP(), []int{18} +} + +func (x *SequenceWithKey) GetSequenceCursor() string { + if x != nil { + return x.SequenceCursor + } + return "" +} + +func (x *SequenceWithKey) GetHead() *Head { + if x != nil { + return x.Head + } + return nil +} + +func (x *SequenceWithKey) GetData() *VersionedBytes { + if x != nil { + return x.Data + } + return nil +} + +func (x *SequenceWithKey) GetKey() string { + if x != nil { + return x.Key + } + return "" +} + // BoundContract represents a [github.com/smartcontractkit/chainlink-common/pkg/types.BoundContract]. type BoundContract struct { state protoimpl.MessageState @@ -1182,7 +1420,7 @@ type BoundContract struct { func (x *BoundContract) Reset() { *x = BoundContract{} if protoimpl.UnsafeEnabled { - mi := &file_contract_reader_proto_msgTypes[15] + mi := &file_contract_reader_proto_msgTypes[19] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1195,7 +1433,7 @@ func (x *BoundContract) String() string { func (*BoundContract) ProtoMessage() {} func (x *BoundContract) ProtoReflect() protoreflect.Message { - mi := &file_contract_reader_proto_msgTypes[15] + mi := &file_contract_reader_proto_msgTypes[19] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1208,7 +1446,7 @@ func (x *BoundContract) ProtoReflect() protoreflect.Message { // Deprecated: Use BoundContract.ProtoReflect.Descriptor instead. func (*BoundContract) Descriptor() ([]byte, []int) { - return file_contract_reader_proto_rawDescGZIP(), []int{15} + return file_contract_reader_proto_rawDescGZIP(), []int{19} } func (x *BoundContract) GetAddress() string { @@ -1238,7 +1476,7 @@ type QueryKeyFilter struct { func (x *QueryKeyFilter) Reset() { *x = QueryKeyFilter{} if protoimpl.UnsafeEnabled { - mi := &file_contract_reader_proto_msgTypes[16] + mi := &file_contract_reader_proto_msgTypes[20] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1251,7 +1489,7 @@ func (x *QueryKeyFilter) String() string { func (*QueryKeyFilter) ProtoMessage() {} func (x *QueryKeyFilter) ProtoReflect() protoreflect.Message { - mi := &file_contract_reader_proto_msgTypes[16] + mi := &file_contract_reader_proto_msgTypes[20] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1264,7 +1502,7 @@ func (x *QueryKeyFilter) ProtoReflect() protoreflect.Message { // Deprecated: Use QueryKeyFilter.ProtoReflect.Descriptor instead. func (*QueryKeyFilter) Descriptor() ([]byte, []int) { - return file_contract_reader_proto_rawDescGZIP(), []int{16} + return file_contract_reader_proto_rawDescGZIP(), []int{20} } func (x *QueryKeyFilter) GetKey() string { @@ -1298,7 +1536,7 @@ type Expression struct { func (x *Expression) Reset() { *x = Expression{} if protoimpl.UnsafeEnabled { - mi := &file_contract_reader_proto_msgTypes[17] + mi := &file_contract_reader_proto_msgTypes[21] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1311,7 +1549,7 @@ func (x *Expression) String() string { func (*Expression) ProtoMessage() {} func (x *Expression) ProtoReflect() protoreflect.Message { - mi := &file_contract_reader_proto_msgTypes[17] + mi := &file_contract_reader_proto_msgTypes[21] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1324,7 +1562,7 @@ func (x *Expression) ProtoReflect() protoreflect.Message { // Deprecated: Use Expression.ProtoReflect.Descriptor instead. func (*Expression) Descriptor() ([]byte, []int) { - return file_contract_reader_proto_rawDescGZIP(), []int{17} + return file_contract_reader_proto_rawDescGZIP(), []int{21} } func (m *Expression) GetEvaluator() isExpression_Evaluator { @@ -1376,7 +1614,7 @@ type BooleanExpression struct { func (x *BooleanExpression) Reset() { *x = BooleanExpression{} if protoimpl.UnsafeEnabled { - mi := &file_contract_reader_proto_msgTypes[18] + mi := &file_contract_reader_proto_msgTypes[22] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1389,7 +1627,7 @@ func (x *BooleanExpression) String() string { func (*BooleanExpression) ProtoMessage() {} func (x *BooleanExpression) ProtoReflect() protoreflect.Message { - mi := &file_contract_reader_proto_msgTypes[18] + mi := &file_contract_reader_proto_msgTypes[22] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1402,7 +1640,7 @@ func (x *BooleanExpression) ProtoReflect() protoreflect.Message { // Deprecated: Use BooleanExpression.ProtoReflect.Descriptor instead. func (*BooleanExpression) Descriptor() ([]byte, []int) { - return file_contract_reader_proto_rawDescGZIP(), []int{18} + return file_contract_reader_proto_rawDescGZIP(), []int{22} } func (x *BooleanExpression) GetBooleanOperator() BooleanOperator { @@ -1430,7 +1668,7 @@ type And struct { func (x *And) Reset() { *x = And{} if protoimpl.UnsafeEnabled { - mi := &file_contract_reader_proto_msgTypes[19] + mi := &file_contract_reader_proto_msgTypes[23] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1443,7 +1681,7 @@ func (x *And) String() string { func (*And) ProtoMessage() {} func (x *And) ProtoReflect() protoreflect.Message { - mi := &file_contract_reader_proto_msgTypes[19] + mi := &file_contract_reader_proto_msgTypes[23] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1456,7 +1694,7 @@ func (x *And) ProtoReflect() protoreflect.Message { // Deprecated: Use And.ProtoReflect.Descriptor instead. func (*And) Descriptor() ([]byte, []int) { - return file_contract_reader_proto_rawDescGZIP(), []int{19} + return file_contract_reader_proto_rawDescGZIP(), []int{23} } func (x *And) GetExpr() []*Expression { @@ -1477,7 +1715,7 @@ type Or struct { func (x *Or) Reset() { *x = Or{} if protoimpl.UnsafeEnabled { - mi := &file_contract_reader_proto_msgTypes[20] + mi := &file_contract_reader_proto_msgTypes[24] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1490,7 +1728,7 @@ func (x *Or) String() string { func (*Or) ProtoMessage() {} func (x *Or) ProtoReflect() protoreflect.Message { - mi := &file_contract_reader_proto_msgTypes[20] + mi := &file_contract_reader_proto_msgTypes[24] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1503,7 +1741,7 @@ func (x *Or) ProtoReflect() protoreflect.Message { // Deprecated: Use Or.ProtoReflect.Descriptor instead. func (*Or) Descriptor() ([]byte, []int) { - return file_contract_reader_proto_rawDescGZIP(), []int{20} + return file_contract_reader_proto_rawDescGZIP(), []int{24} } func (x *Or) GetExpr() []*Expression { @@ -1525,7 +1763,7 @@ type ValueComparator struct { func (x *ValueComparator) Reset() { *x = ValueComparator{} if protoimpl.UnsafeEnabled { - mi := &file_contract_reader_proto_msgTypes[21] + mi := &file_contract_reader_proto_msgTypes[25] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1538,7 +1776,7 @@ func (x *ValueComparator) String() string { func (*ValueComparator) ProtoMessage() {} func (x *ValueComparator) ProtoReflect() protoreflect.Message { - mi := &file_contract_reader_proto_msgTypes[21] + mi := &file_contract_reader_proto_msgTypes[25] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1551,7 +1789,7 @@ func (x *ValueComparator) ProtoReflect() protoreflect.Message { // Deprecated: Use ValueComparator.ProtoReflect.Descriptor instead. func (*ValueComparator) Descriptor() ([]byte, []int) { - return file_contract_reader_proto_rawDescGZIP(), []int{21} + return file_contract_reader_proto_rawDescGZIP(), []int{25} } func (x *ValueComparator) GetValue() *VersionedBytes { @@ -1580,7 +1818,7 @@ type Comparator struct { func (x *Comparator) Reset() { *x = Comparator{} if protoimpl.UnsafeEnabled { - mi := &file_contract_reader_proto_msgTypes[22] + mi := &file_contract_reader_proto_msgTypes[26] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1593,7 +1831,7 @@ func (x *Comparator) String() string { func (*Comparator) ProtoMessage() {} func (x *Comparator) ProtoReflect() protoreflect.Message { - mi := &file_contract_reader_proto_msgTypes[22] + mi := &file_contract_reader_proto_msgTypes[26] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1606,7 +1844,7 @@ func (x *Comparator) ProtoReflect() protoreflect.Message { // Deprecated: Use Comparator.ProtoReflect.Descriptor instead. func (*Comparator) Descriptor() ([]byte, []int) { - return file_contract_reader_proto_rawDescGZIP(), []int{22} + return file_contract_reader_proto_rawDescGZIP(), []int{26} } func (x *Comparator) GetName() string { @@ -1635,7 +1873,7 @@ type Block struct { func (x *Block) Reset() { *x = Block{} if protoimpl.UnsafeEnabled { - mi := &file_contract_reader_proto_msgTypes[23] + mi := &file_contract_reader_proto_msgTypes[27] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1648,7 +1886,7 @@ func (x *Block) String() string { func (*Block) ProtoMessage() {} func (x *Block) ProtoReflect() protoreflect.Message { - mi := &file_contract_reader_proto_msgTypes[23] + mi := &file_contract_reader_proto_msgTypes[27] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1661,7 +1899,7 @@ func (x *Block) ProtoReflect() protoreflect.Message { // Deprecated: Use Block.ProtoReflect.Descriptor instead. func (*Block) Descriptor() ([]byte, []int) { - return file_contract_reader_proto_rawDescGZIP(), []int{23} + return file_contract_reader_proto_rawDescGZIP(), []int{27} } func (x *Block) GetBlockNumber() string { @@ -1690,7 +1928,7 @@ type Timestamp struct { func (x *Timestamp) Reset() { *x = Timestamp{} if protoimpl.UnsafeEnabled { - mi := &file_contract_reader_proto_msgTypes[24] + mi := &file_contract_reader_proto_msgTypes[28] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1703,7 +1941,7 @@ func (x *Timestamp) String() string { func (*Timestamp) ProtoMessage() {} func (x *Timestamp) ProtoReflect() protoreflect.Message { - mi := &file_contract_reader_proto_msgTypes[24] + mi := &file_contract_reader_proto_msgTypes[28] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1716,7 +1954,7 @@ func (x *Timestamp) ProtoReflect() protoreflect.Message { // Deprecated: Use Timestamp.ProtoReflect.Descriptor instead. func (*Timestamp) Descriptor() ([]byte, []int) { - return file_contract_reader_proto_rawDescGZIP(), []int{24} + return file_contract_reader_proto_rawDescGZIP(), []int{28} } func (x *Timestamp) GetTimestamp() uint64 { @@ -1744,7 +1982,7 @@ type TxHash struct { func (x *TxHash) Reset() { *x = TxHash{} if protoimpl.UnsafeEnabled { - mi := &file_contract_reader_proto_msgTypes[25] + mi := &file_contract_reader_proto_msgTypes[29] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1757,7 +1995,7 @@ func (x *TxHash) String() string { func (*TxHash) ProtoMessage() {} func (x *TxHash) ProtoReflect() protoreflect.Message { - mi := &file_contract_reader_proto_msgTypes[25] + mi := &file_contract_reader_proto_msgTypes[29] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1770,7 +2008,7 @@ func (x *TxHash) ProtoReflect() protoreflect.Message { // Deprecated: Use TxHash.ProtoReflect.Descriptor instead. func (*TxHash) Descriptor() ([]byte, []int) { - return file_contract_reader_proto_rawDescGZIP(), []int{25} + return file_contract_reader_proto_rawDescGZIP(), []int{29} } func (x *TxHash) GetTxHash() string { @@ -1799,7 +2037,7 @@ type Primitive struct { func (x *Primitive) Reset() { *x = Primitive{} if protoimpl.UnsafeEnabled { - mi := &file_contract_reader_proto_msgTypes[26] + mi := &file_contract_reader_proto_msgTypes[30] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1812,7 +2050,7 @@ func (x *Primitive) String() string { func (*Primitive) ProtoMessage() {} func (x *Primitive) ProtoReflect() protoreflect.Message { - mi := &file_contract_reader_proto_msgTypes[26] + mi := &file_contract_reader_proto_msgTypes[30] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1825,7 +2063,7 @@ func (x *Primitive) ProtoReflect() protoreflect.Message { // Deprecated: Use Primitive.ProtoReflect.Descriptor instead. func (*Primitive) Descriptor() ([]byte, []int) { - return file_contract_reader_proto_rawDescGZIP(), []int{26} + return file_contract_reader_proto_rawDescGZIP(), []int{30} } func (m *Primitive) GetPrimitive() isPrimitive_Primitive { @@ -1918,7 +2156,7 @@ type Limit struct { func (x *Limit) Reset() { *x = Limit{} if protoimpl.UnsafeEnabled { - mi := &file_contract_reader_proto_msgTypes[27] + mi := &file_contract_reader_proto_msgTypes[31] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1931,7 +2169,7 @@ func (x *Limit) String() string { func (*Limit) ProtoMessage() {} func (x *Limit) ProtoReflect() protoreflect.Message { - mi := &file_contract_reader_proto_msgTypes[27] + mi := &file_contract_reader_proto_msgTypes[31] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1944,7 +2182,7 @@ func (x *Limit) ProtoReflect() protoreflect.Message { // Deprecated: Use Limit.ProtoReflect.Descriptor instead. func (*Limit) Descriptor() ([]byte, []int) { - return file_contract_reader_proto_rawDescGZIP(), []int{27} + return file_contract_reader_proto_rawDescGZIP(), []int{31} } func (x *Limit) GetCursor() string { @@ -1980,7 +2218,7 @@ type SortBy struct { func (x *SortBy) Reset() { *x = SortBy{} if protoimpl.UnsafeEnabled { - mi := &file_contract_reader_proto_msgTypes[28] + mi := &file_contract_reader_proto_msgTypes[32] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1993,7 +2231,7 @@ func (x *SortBy) String() string { func (*SortBy) ProtoMessage() {} func (x *SortBy) ProtoReflect() protoreflect.Message { - mi := &file_contract_reader_proto_msgTypes[28] + mi := &file_contract_reader_proto_msgTypes[32] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2006,7 +2244,7 @@ func (x *SortBy) ProtoReflect() protoreflect.Message { // Deprecated: Use SortBy.ProtoReflect.Descriptor instead. func (*SortBy) Descriptor() ([]byte, []int) { - return file_contract_reader_proto_rawDescGZIP(), []int{28} + return file_contract_reader_proto_rawDescGZIP(), []int{32} } func (x *SortBy) GetSortType() SortType { @@ -2036,7 +2274,7 @@ type LimitAndSort struct { func (x *LimitAndSort) Reset() { *x = LimitAndSort{} if protoimpl.UnsafeEnabled { - mi := &file_contract_reader_proto_msgTypes[29] + mi := &file_contract_reader_proto_msgTypes[33] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2049,7 +2287,7 @@ func (x *LimitAndSort) String() string { func (*LimitAndSort) ProtoMessage() {} func (x *LimitAndSort) ProtoReflect() protoreflect.Message { - mi := &file_contract_reader_proto_msgTypes[29] + mi := &file_contract_reader_proto_msgTypes[33] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2062,7 +2300,7 @@ func (x *LimitAndSort) ProtoReflect() protoreflect.Message { // Deprecated: Use LimitAndSort.ProtoReflect.Descriptor instead. func (*LimitAndSort) Descriptor() ([]byte, []int) { - return file_contract_reader_proto_rawDescGZIP(), []int{29} + return file_contract_reader_proto_rawDescGZIP(), []int{33} } func (x *LimitAndSort) GetSortBy() []*SortBy { @@ -2117,230 +2355,266 @@ var file_contract_reader_proto_rawDesc = []byte{ 0x69, 0x6d, 0x69, 0x74, 0x41, 0x6e, 0x64, 0x53, 0x6f, 0x72, 0x74, 0x12, 0x22, 0x0a, 0x0d, 0x61, 0x73, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x61, 0x73, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x54, 0x79, 0x70, 0x65, 0x22, - 0x3e, 0x0a, 0x0b, 0x42, 0x69, 0x6e, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x2f, - 0x0a, 0x08, 0x62, 0x69, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, - 0x32, 0x13, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x2e, 0x42, 0x6f, 0x75, 0x6e, 0x64, 0x43, 0x6f, 0x6e, - 0x74, 0x72, 0x61, 0x63, 0x74, 0x52, 0x08, 0x62, 0x69, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x73, 0x22, - 0x40, 0x0a, 0x0d, 0x55, 0x6e, 0x62, 0x69, 0x6e, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x12, 0x2f, 0x0a, 0x08, 0x62, 0x69, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x73, 0x18, 0x01, 0x20, 0x03, - 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x2e, 0x42, 0x6f, 0x75, 0x6e, 0x64, 0x43, - 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, 0x52, 0x08, 0x62, 0x69, 0x6e, 0x64, 0x69, 0x6e, 0x67, - 0x73, 0x22, 0x44, 0x0a, 0x13, 0x47, 0x65, 0x74, 0x4c, 0x61, 0x74, 0x65, 0x73, 0x74, 0x56, 0x61, - 0x6c, 0x75, 0x65, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x12, 0x2d, 0x0a, 0x07, 0x72, 0x65, 0x74, 0x5f, - 0x76, 0x61, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, - 0x2e, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x64, 0x42, 0x79, 0x74, 0x65, 0x73, 0x52, - 0x06, 0x72, 0x65, 0x74, 0x56, 0x61, 0x6c, 0x22, 0x79, 0x0a, 0x1f, 0x47, 0x65, 0x74, 0x4c, 0x61, - 0x74, 0x65, 0x73, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x57, 0x69, 0x74, 0x68, 0x48, 0x65, 0x61, - 0x64, 0x44, 0x61, 0x74, 0x61, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x12, 0x2d, 0x0a, 0x07, 0x72, 0x65, - 0x74, 0x5f, 0x76, 0x61, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x6c, 0x6f, - 0x6f, 0x70, 0x2e, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x64, 0x42, 0x79, 0x74, 0x65, - 0x73, 0x52, 0x06, 0x72, 0x65, 0x74, 0x56, 0x61, 0x6c, 0x12, 0x27, 0x0a, 0x09, 0x68, 0x65, 0x61, - 0x64, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0a, 0x2e, 0x6c, - 0x6f, 0x6f, 0x70, 0x2e, 0x48, 0x65, 0x61, 0x64, 0x52, 0x08, 0x68, 0x65, 0x61, 0x64, 0x44, 0x61, - 0x74, 0x61, 0x22, 0x50, 0x0a, 0x19, 0x42, 0x61, 0x74, 0x63, 0x68, 0x47, 0x65, 0x74, 0x4c, 0x61, - 0x74, 0x65, 0x73, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x12, - 0x33, 0x0a, 0x07, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, - 0x32, 0x19, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, - 0x42, 0x61, 0x74, 0x63, 0x68, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x52, 0x07, 0x72, 0x65, 0x73, - 0x75, 0x6c, 0x74, 0x73, 0x22, 0x3d, 0x0a, 0x0d, 0x51, 0x75, 0x65, 0x72, 0x79, 0x4b, 0x65, 0x79, - 0x52, 0x65, 0x70, 0x6c, 0x79, 0x12, 0x2c, 0x0a, 0x09, 0x73, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, - 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x2e, - 0x53, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x65, 0x52, 0x09, 0x73, 0x65, 0x71, 0x75, 0x65, 0x6e, - 0x63, 0x65, 0x73, 0x22, 0x67, 0x0a, 0x0d, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, 0x42, - 0x61, 0x74, 0x63, 0x68, 0x12, 0x2f, 0x0a, 0x08, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x2e, 0x42, 0x6f, - 0x75, 0x6e, 0x64, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, 0x52, 0x08, 0x63, 0x6f, 0x6e, - 0x74, 0x72, 0x61, 0x63, 0x74, 0x12, 0x25, 0x0a, 0x05, 0x72, 0x65, 0x61, 0x64, 0x73, 0x18, 0x02, - 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x2e, 0x42, 0x61, 0x74, 0x63, - 0x68, 0x52, 0x65, 0x61, 0x64, 0x52, 0x05, 0x72, 0x65, 0x61, 0x64, 0x73, 0x22, 0x8b, 0x01, 0x0a, - 0x09, 0x42, 0x61, 0x74, 0x63, 0x68, 0x52, 0x65, 0x61, 0x64, 0x12, 0x1b, 0x0a, 0x09, 0x72, 0x65, - 0x61, 0x64, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x72, - 0x65, 0x61, 0x64, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x2c, 0x0a, 0x06, 0x70, 0x61, 0x72, 0x61, 0x6d, - 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x2e, 0x56, - 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x64, 0x42, 0x79, 0x74, 0x65, 0x73, 0x52, 0x06, 0x70, - 0x61, 0x72, 0x61, 0x6d, 0x73, 0x12, 0x33, 0x0a, 0x0a, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x5f, - 0x76, 0x61, 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, - 0x2e, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x64, 0x42, 0x79, 0x74, 0x65, 0x73, 0x52, - 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x56, 0x61, 0x6c, 0x22, 0x77, 0x0a, 0x13, 0x43, 0x6f, - 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, 0x42, 0x61, 0x74, 0x63, 0x68, 0x52, 0x65, 0x73, 0x75, 0x6c, - 0x74, 0x12, 0x2f, 0x0a, 0x08, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x2e, 0x42, 0x6f, 0x75, 0x6e, 0x64, - 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, 0x52, 0x08, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x61, - 0x63, 0x74, 0x12, 0x2f, 0x0a, 0x07, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x18, 0x02, 0x20, - 0x03, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x2e, 0x42, 0x61, 0x74, 0x63, 0x68, - 0x52, 0x65, 0x61, 0x64, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x52, 0x07, 0x72, 0x65, 0x73, 0x75, - 0x6c, 0x74, 0x73, 0x22, 0x79, 0x0a, 0x0f, 0x42, 0x61, 0x74, 0x63, 0x68, 0x52, 0x65, 0x61, 0x64, - 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x72, 0x65, 0x61, 0x64, 0x5f, 0x6e, - 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x72, 0x65, 0x61, 0x64, 0x4e, - 0x61, 0x6d, 0x65, 0x12, 0x33, 0x0a, 0x0a, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x5f, 0x76, 0x61, - 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x2e, 0x56, - 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x64, 0x42, 0x79, 0x74, 0x65, 0x73, 0x52, 0x09, 0x72, - 0x65, 0x74, 0x75, 0x72, 0x6e, 0x56, 0x61, 0x6c, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, - 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x22, 0x50, - 0x0a, 0x04, 0x48, 0x65, 0x61, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x12, 0x12, - 0x0a, 0x04, 0x68, 0x61, 0x73, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x68, 0x61, - 0x73, 0x68, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, - 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, - 0x22, 0x7d, 0x0a, 0x08, 0x53, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x65, 0x12, 0x27, 0x0a, 0x0f, - 0x73, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x65, 0x5f, 0x63, 0x75, 0x72, 0x73, 0x6f, 0x72, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x73, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x65, 0x43, - 0x75, 0x72, 0x73, 0x6f, 0x72, 0x12, 0x1e, 0x0a, 0x04, 0x68, 0x65, 0x61, 0x64, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x0a, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x2e, 0x48, 0x65, 0x61, 0x64, 0x52, - 0x04, 0x68, 0x65, 0x61, 0x64, 0x12, 0x28, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x03, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x2e, 0x56, 0x65, 0x72, 0x73, 0x69, - 0x6f, 0x6e, 0x65, 0x64, 0x42, 0x79, 0x74, 0x65, 0x73, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x22, - 0x3d, 0x0a, 0x0d, 0x42, 0x6f, 0x75, 0x6e, 0x64, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, - 0x12, 0x18, 0x0a, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, - 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x54, - 0x0a, 0x0e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x4b, 0x65, 0x79, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, - 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, - 0x65, 0x79, 0x12, 0x30, 0x0a, 0x0a, 0x65, 0x78, 0x70, 0x72, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, - 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x2e, 0x45, 0x78, - 0x70, 0x72, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x0a, 0x65, 0x78, 0x70, 0x72, 0x65, 0x73, - 0x73, 0x69, 0x6f, 0x6e, 0x22, 0x94, 0x01, 0x0a, 0x0a, 0x45, 0x78, 0x70, 0x72, 0x65, 0x73, 0x73, - 0x69, 0x6f, 0x6e, 0x12, 0x2f, 0x0a, 0x09, 0x70, 0x72, 0x69, 0x6d, 0x69, 0x74, 0x69, 0x76, 0x65, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x2e, 0x50, 0x72, - 0x69, 0x6d, 0x69, 0x74, 0x69, 0x76, 0x65, 0x48, 0x00, 0x52, 0x09, 0x70, 0x72, 0x69, 0x6d, 0x69, - 0x74, 0x69, 0x76, 0x65, 0x12, 0x48, 0x0a, 0x12, 0x62, 0x6f, 0x6f, 0x6c, 0x65, 0x61, 0x6e, 0x5f, - 0x65, 0x78, 0x70, 0x72, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x17, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x2e, 0x42, 0x6f, 0x6f, 0x6c, 0x65, 0x61, 0x6e, 0x45, - 0x78, 0x70, 0x72, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x48, 0x00, 0x52, 0x11, 0x62, 0x6f, 0x6f, - 0x6c, 0x65, 0x61, 0x6e, 0x45, 0x78, 0x70, 0x72, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x42, 0x0b, - 0x0a, 0x09, 0x65, 0x76, 0x61, 0x6c, 0x75, 0x61, 0x74, 0x6f, 0x72, 0x22, 0x87, 0x01, 0x0a, 0x11, - 0x42, 0x6f, 0x6f, 0x6c, 0x65, 0x61, 0x6e, 0x45, 0x78, 0x70, 0x72, 0x65, 0x73, 0x73, 0x69, 0x6f, - 0x6e, 0x12, 0x40, 0x0a, 0x10, 0x62, 0x6f, 0x6f, 0x6c, 0x65, 0x61, 0x6e, 0x5f, 0x6f, 0x70, 0x65, - 0x72, 0x61, 0x74, 0x6f, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x15, 0x2e, 0x6c, 0x6f, - 0x6f, 0x70, 0x2e, 0x42, 0x6f, 0x6f, 0x6c, 0x65, 0x61, 0x6e, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, - 0x6f, 0x72, 0x52, 0x0f, 0x62, 0x6f, 0x6f, 0x6c, 0x65, 0x61, 0x6e, 0x4f, 0x70, 0x65, 0x72, 0x61, - 0x74, 0x6f, 0x72, 0x12, 0x30, 0x0a, 0x0a, 0x65, 0x78, 0x70, 0x72, 0x65, 0x73, 0x73, 0x69, 0x6f, - 0x6e, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x2e, 0x45, - 0x78, 0x70, 0x72, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x0a, 0x65, 0x78, 0x70, 0x72, 0x65, - 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0x2b, 0x0a, 0x03, 0x41, 0x6e, 0x64, 0x12, 0x24, 0x0a, 0x04, - 0x65, 0x78, 0x70, 0x72, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x6c, 0x6f, 0x6f, - 0x70, 0x2e, 0x45, 0x78, 0x70, 0x72, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x04, 0x65, 0x78, - 0x70, 0x72, 0x22, 0x2a, 0x0a, 0x02, 0x4f, 0x72, 0x12, 0x24, 0x0a, 0x04, 0x65, 0x78, 0x70, 0x72, - 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x2e, 0x45, 0x78, - 0x70, 0x72, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x04, 0x65, 0x78, 0x70, 0x72, 0x22, 0x73, - 0x0a, 0x0f, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x43, 0x6f, 0x6d, 0x70, 0x61, 0x72, 0x61, 0x74, 0x6f, - 0x72, 0x12, 0x2a, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x14, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x2e, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x65, - 0x64, 0x42, 0x79, 0x74, 0x65, 0x73, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x34, 0x0a, - 0x08, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, - 0x18, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x2e, 0x43, 0x6f, 0x6d, 0x70, 0x61, 0x72, 0x69, 0x73, 0x6f, - 0x6e, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x52, 0x08, 0x6f, 0x70, 0x65, 0x72, 0x61, - 0x74, 0x6f, 0x72, 0x22, 0x64, 0x0a, 0x0a, 0x43, 0x6f, 0x6d, 0x70, 0x61, 0x72, 0x61, 0x74, 0x6f, - 0x72, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x42, 0x0a, 0x11, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x5f, 0x63, - 0x6f, 0x6d, 0x70, 0x61, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, - 0x32, 0x15, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x2e, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x43, 0x6f, 0x6d, - 0x70, 0x61, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x52, 0x10, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x43, 0x6f, - 0x6d, 0x70, 0x61, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x73, 0x22, 0x60, 0x0a, 0x05, 0x42, 0x6c, 0x6f, - 0x63, 0x6b, 0x12, 0x21, 0x0a, 0x0c, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x6e, 0x75, 0x6d, 0x62, - 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x4e, - 0x75, 0x6d, 0x62, 0x65, 0x72, 0x12, 0x34, 0x0a, 0x08, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, - 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x18, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x2e, 0x43, - 0x6f, 0x6d, 0x70, 0x61, 0x72, 0x69, 0x73, 0x6f, 0x6e, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, - 0x72, 0x52, 0x08, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x22, 0x5f, 0x0a, 0x09, 0x54, - 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, - 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, 0x74, 0x69, 0x6d, - 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x34, 0x0a, 0x08, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, - 0x6f, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x18, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x2e, - 0x43, 0x6f, 0x6d, 0x70, 0x61, 0x72, 0x69, 0x73, 0x6f, 0x6e, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, - 0x6f, 0x72, 0x52, 0x08, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x22, 0x21, 0x0a, 0x06, - 0x54, 0x78, 0x48, 0x61, 0x73, 0x68, 0x12, 0x17, 0x0a, 0x07, 0x74, 0x78, 0x5f, 0x68, 0x61, 0x73, - 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x74, 0x78, 0x48, 0x61, 0x73, 0x68, 0x22, - 0xff, 0x01, 0x0a, 0x09, 0x50, 0x72, 0x69, 0x6d, 0x69, 0x74, 0x69, 0x76, 0x65, 0x12, 0x32, 0x0a, - 0x0a, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x10, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x2e, 0x43, 0x6f, 0x6d, 0x70, 0x61, 0x72, 0x61, - 0x74, 0x6f, 0x72, 0x48, 0x00, 0x52, 0x0a, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x72, 0x61, 0x74, 0x6f, - 0x72, 0x12, 0x23, 0x0a, 0x05, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x0b, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x2e, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x48, 0x00, 0x52, - 0x05, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x12, 0x32, 0x0a, 0x0a, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x64, - 0x65, 0x6e, 0x63, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x10, 0x2e, 0x6c, 0x6f, 0x6f, - 0x70, 0x2e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x64, 0x65, 0x6e, 0x63, 0x65, 0x48, 0x00, 0x52, 0x0a, - 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x64, 0x65, 0x6e, 0x63, 0x65, 0x12, 0x2f, 0x0a, 0x09, 0x74, 0x69, - 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, - 0x6c, 0x6f, 0x6f, 0x70, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x48, 0x00, - 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x27, 0x0a, 0x07, 0x74, - 0x78, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x6c, - 0x6f, 0x6f, 0x70, 0x2e, 0x54, 0x78, 0x48, 0x61, 0x73, 0x68, 0x48, 0x00, 0x52, 0x06, 0x74, 0x78, - 0x48, 0x61, 0x73, 0x68, 0x42, 0x0b, 0x0a, 0x09, 0x70, 0x72, 0x69, 0x6d, 0x69, 0x74, 0x69, 0x76, - 0x65, 0x22, 0x8d, 0x01, 0x0a, 0x05, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x12, 0x1b, 0x0a, 0x06, 0x63, - 0x75, 0x72, 0x73, 0x6f, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x06, 0x63, - 0x75, 0x72, 0x73, 0x6f, 0x72, 0x88, 0x01, 0x01, 0x12, 0x38, 0x0a, 0x09, 0x64, 0x69, 0x72, 0x65, - 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x15, 0x2e, 0x6c, 0x6f, - 0x6f, 0x70, 0x2e, 0x43, 0x75, 0x72, 0x73, 0x6f, 0x72, 0x44, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, - 0x6f, 0x6e, 0x48, 0x01, 0x52, 0x09, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x88, - 0x01, 0x01, 0x12, 0x14, 0x0a, 0x05, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, - 0x04, 0x52, 0x05, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x42, 0x09, 0x0a, 0x07, 0x5f, 0x63, 0x75, 0x72, - 0x73, 0x6f, 0x72, 0x42, 0x0c, 0x0a, 0x0a, 0x5f, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6f, - 0x6e, 0x22, 0x68, 0x0a, 0x06, 0x53, 0x6f, 0x72, 0x74, 0x42, 0x79, 0x12, 0x2b, 0x0a, 0x09, 0x73, - 0x6f, 0x72, 0x74, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x0e, - 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x2e, 0x53, 0x6f, 0x72, 0x74, 0x54, 0x79, 0x70, 0x65, 0x52, 0x08, - 0x73, 0x6f, 0x72, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x31, 0x0a, 0x09, 0x64, 0x69, 0x72, 0x65, - 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x13, 0x2e, 0x6c, 0x6f, - 0x6f, 0x70, 0x2e, 0x53, 0x6f, 0x72, 0x74, 0x44, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, - 0x52, 0x09, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x58, 0x0a, 0x0c, 0x4c, - 0x69, 0x6d, 0x69, 0x74, 0x41, 0x6e, 0x64, 0x53, 0x6f, 0x72, 0x74, 0x12, 0x25, 0x0a, 0x07, 0x73, - 0x6f, 0x72, 0x74, 0x5f, 0x62, 0x79, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x6c, - 0x6f, 0x6f, 0x70, 0x2e, 0x53, 0x6f, 0x72, 0x74, 0x42, 0x79, 0x52, 0x06, 0x73, 0x6f, 0x72, 0x74, - 0x42, 0x79, 0x12, 0x21, 0x0a, 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x0b, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x2e, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x52, 0x05, - 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x2a, 0x47, 0x0a, 0x12, 0x43, 0x6f, 0x6d, 0x70, 0x61, 0x72, 0x69, - 0x73, 0x6f, 0x6e, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x12, 0x06, 0x0a, 0x02, 0x45, - 0x71, 0x10, 0x00, 0x12, 0x07, 0x0a, 0x03, 0x4e, 0x65, 0x71, 0x10, 0x01, 0x12, 0x06, 0x0a, 0x02, - 0x47, 0x74, 0x10, 0x02, 0x12, 0x06, 0x0a, 0x02, 0x4c, 0x74, 0x10, 0x03, 0x12, 0x07, 0x0a, 0x03, - 0x47, 0x74, 0x65, 0x10, 0x04, 0x12, 0x07, 0x0a, 0x03, 0x4c, 0x74, 0x65, 0x10, 0x05, 0x2a, 0x22, - 0x0a, 0x0f, 0x42, 0x6f, 0x6f, 0x6c, 0x65, 0x61, 0x6e, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, - 0x72, 0x12, 0x07, 0x0a, 0x03, 0x41, 0x4e, 0x44, 0x10, 0x00, 0x12, 0x06, 0x0a, 0x02, 0x4f, 0x52, - 0x10, 0x01, 0x2a, 0x2c, 0x0a, 0x0a, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x64, 0x65, 0x6e, 0x63, 0x65, - 0x12, 0x0f, 0x0a, 0x0b, 0x55, 0x6e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x72, 0x6d, 0x65, 0x64, 0x10, - 0x00, 0x12, 0x0d, 0x0a, 0x09, 0x46, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x64, 0x10, 0x01, - 0x2a, 0x2f, 0x0a, 0x0f, 0x43, 0x75, 0x72, 0x73, 0x6f, 0x72, 0x44, 0x69, 0x72, 0x65, 0x63, 0x74, - 0x69, 0x6f, 0x6e, 0x12, 0x0d, 0x0a, 0x09, 0x50, 0x72, 0x65, 0x63, 0x65, 0x64, 0x69, 0x6e, 0x67, - 0x10, 0x00, 0x12, 0x0d, 0x0a, 0x09, 0x46, 0x6f, 0x6c, 0x6c, 0x6f, 0x77, 0x69, 0x6e, 0x67, 0x10, - 0x01, 0x2a, 0x22, 0x0a, 0x0d, 0x53, 0x6f, 0x72, 0x74, 0x44, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, - 0x6f, 0x6e, 0x12, 0x07, 0x0a, 0x03, 0x41, 0x73, 0x63, 0x10, 0x00, 0x12, 0x08, 0x0a, 0x04, 0x44, - 0x65, 0x73, 0x63, 0x10, 0x01, 0x2a, 0x3e, 0x0a, 0x08, 0x53, 0x6f, 0x72, 0x74, 0x54, 0x79, 0x70, - 0x65, 0x12, 0x11, 0x0a, 0x0d, 0x53, 0x6f, 0x72, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, - 0x6d, 0x70, 0x10, 0x00, 0x12, 0x0d, 0x0a, 0x09, 0x53, 0x6f, 0x72, 0x74, 0x42, 0x6c, 0x6f, 0x63, - 0x6b, 0x10, 0x01, 0x12, 0x10, 0x0a, 0x0c, 0x53, 0x6f, 0x72, 0x74, 0x53, 0x65, 0x71, 0x75, 0x65, - 0x6e, 0x63, 0x65, 0x10, 0x02, 0x32, 0xc6, 0x03, 0x0a, 0x0e, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x61, - 0x63, 0x74, 0x52, 0x65, 0x61, 0x64, 0x65, 0x72, 0x12, 0x4a, 0x0a, 0x0e, 0x47, 0x65, 0x74, 0x4c, - 0x61, 0x74, 0x65, 0x73, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x1b, 0x2e, 0x6c, 0x6f, 0x6f, - 0x70, 0x2e, 0x47, 0x65, 0x74, 0x4c, 0x61, 0x74, 0x65, 0x73, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x19, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x2e, 0x47, + 0x7f, 0x0a, 0x10, 0x51, 0x75, 0x65, 0x72, 0x79, 0x4b, 0x65, 0x79, 0x73, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x12, 0x31, 0x0a, 0x07, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x73, 0x18, 0x01, + 0x20, 0x03, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x2e, 0x43, 0x6f, 0x6e, 0x74, + 0x72, 0x61, 0x63, 0x74, 0x4b, 0x65, 0x79, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x52, 0x07, 0x66, + 0x69, 0x6c, 0x74, 0x65, 0x72, 0x73, 0x12, 0x38, 0x0a, 0x0e, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x5f, + 0x61, 0x6e, 0x64, 0x5f, 0x73, 0x6f, 0x72, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, + 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x2e, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x41, 0x6e, 0x64, 0x53, 0x6f, + 0x72, 0x74, 0x52, 0x0c, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x41, 0x6e, 0x64, 0x53, 0x6f, 0x72, 0x74, + 0x22, 0x96, 0x01, 0x0a, 0x11, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, 0x4b, 0x65, 0x79, + 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x12, 0x2f, 0x0a, 0x08, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x61, + 0x63, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x2e, + 0x42, 0x6f, 0x75, 0x6e, 0x64, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, 0x52, 0x08, 0x63, + 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, 0x12, 0x2c, 0x0a, 0x06, 0x66, 0x69, 0x6c, 0x74, 0x65, + 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x2e, 0x51, + 0x75, 0x65, 0x72, 0x79, 0x4b, 0x65, 0x79, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x52, 0x06, 0x66, + 0x69, 0x6c, 0x74, 0x65, 0x72, 0x12, 0x22, 0x0a, 0x0d, 0x61, 0x73, 0x5f, 0x76, 0x61, 0x6c, 0x75, + 0x65, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x61, 0x73, + 0x56, 0x61, 0x6c, 0x75, 0x65, 0x54, 0x79, 0x70, 0x65, 0x22, 0x3e, 0x0a, 0x0b, 0x42, 0x69, 0x6e, + 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x2f, 0x0a, 0x08, 0x62, 0x69, 0x6e, 0x64, + 0x69, 0x6e, 0x67, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x6c, 0x6f, 0x6f, + 0x70, 0x2e, 0x42, 0x6f, 0x75, 0x6e, 0x64, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, 0x52, + 0x08, 0x62, 0x69, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x73, 0x22, 0x40, 0x0a, 0x0d, 0x55, 0x6e, 0x62, + 0x69, 0x6e, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x2f, 0x0a, 0x08, 0x62, 0x69, + 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x6c, + 0x6f, 0x6f, 0x70, 0x2e, 0x42, 0x6f, 0x75, 0x6e, 0x64, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, + 0x74, 0x52, 0x08, 0x62, 0x69, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x73, 0x22, 0x44, 0x0a, 0x13, 0x47, 0x65, 0x74, 0x4c, 0x61, 0x74, 0x65, 0x73, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x65, 0x70, - 0x6c, 0x79, 0x22, 0x00, 0x12, 0x62, 0x0a, 0x1a, 0x47, 0x65, 0x74, 0x4c, 0x61, 0x74, 0x65, 0x73, - 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x57, 0x69, 0x74, 0x68, 0x48, 0x65, 0x61, 0x64, 0x44, 0x61, - 0x74, 0x61, 0x12, 0x1b, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x2e, 0x47, 0x65, 0x74, 0x4c, 0x61, 0x74, - 0x65, 0x73, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, - 0x25, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x2e, 0x47, 0x65, 0x74, 0x4c, 0x61, 0x74, 0x65, 0x73, 0x74, - 0x56, 0x61, 0x6c, 0x75, 0x65, 0x57, 0x69, 0x74, 0x68, 0x48, 0x65, 0x61, 0x64, 0x44, 0x61, 0x74, - 0x61, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x00, 0x12, 0x5c, 0x0a, 0x14, 0x42, 0x61, 0x74, 0x63, - 0x68, 0x47, 0x65, 0x74, 0x4c, 0x61, 0x74, 0x65, 0x73, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x73, - 0x12, 0x21, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x2e, 0x42, 0x61, 0x74, 0x63, 0x68, 0x47, 0x65, 0x74, - 0x4c, 0x61, 0x74, 0x65, 0x73, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x1a, 0x1f, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x2e, 0x42, 0x61, 0x74, 0x63, 0x68, - 0x47, 0x65, 0x74, 0x4c, 0x61, 0x74, 0x65, 0x73, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x52, - 0x65, 0x70, 0x6c, 0x79, 0x22, 0x00, 0x12, 0x38, 0x0a, 0x08, 0x51, 0x75, 0x65, 0x72, 0x79, 0x4b, - 0x65, 0x79, 0x12, 0x15, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x4b, - 0x65, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x13, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, - 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x00, - 0x12, 0x33, 0x0a, 0x04, 0x42, 0x69, 0x6e, 0x64, 0x12, 0x11, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x2e, - 0x42, 0x69, 0x6e, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, + 0x6c, 0x79, 0x12, 0x2d, 0x0a, 0x07, 0x72, 0x65, 0x74, 0x5f, 0x76, 0x61, 0x6c, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x2e, 0x56, 0x65, 0x72, 0x73, 0x69, + 0x6f, 0x6e, 0x65, 0x64, 0x42, 0x79, 0x74, 0x65, 0x73, 0x52, 0x06, 0x72, 0x65, 0x74, 0x56, 0x61, + 0x6c, 0x22, 0x79, 0x0a, 0x1f, 0x47, 0x65, 0x74, 0x4c, 0x61, 0x74, 0x65, 0x73, 0x74, 0x56, 0x61, + 0x6c, 0x75, 0x65, 0x57, 0x69, 0x74, 0x68, 0x48, 0x65, 0x61, 0x64, 0x44, 0x61, 0x74, 0x61, 0x52, + 0x65, 0x70, 0x6c, 0x79, 0x12, 0x2d, 0x0a, 0x07, 0x72, 0x65, 0x74, 0x5f, 0x76, 0x61, 0x6c, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x2e, 0x56, 0x65, 0x72, + 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x64, 0x42, 0x79, 0x74, 0x65, 0x73, 0x52, 0x06, 0x72, 0x65, 0x74, + 0x56, 0x61, 0x6c, 0x12, 0x27, 0x0a, 0x09, 0x68, 0x65, 0x61, 0x64, 0x5f, 0x64, 0x61, 0x74, 0x61, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0a, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x2e, 0x48, 0x65, + 0x61, 0x64, 0x52, 0x08, 0x68, 0x65, 0x61, 0x64, 0x44, 0x61, 0x74, 0x61, 0x22, 0x50, 0x0a, 0x19, + 0x42, 0x61, 0x74, 0x63, 0x68, 0x47, 0x65, 0x74, 0x4c, 0x61, 0x74, 0x65, 0x73, 0x74, 0x56, 0x61, + 0x6c, 0x75, 0x65, 0x73, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x12, 0x33, 0x0a, 0x07, 0x72, 0x65, 0x73, + 0x75, 0x6c, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x6c, 0x6f, 0x6f, + 0x70, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, 0x42, 0x61, 0x74, 0x63, 0x68, 0x52, + 0x65, 0x73, 0x75, 0x6c, 0x74, 0x52, 0x07, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x22, 0x3d, + 0x0a, 0x0d, 0x51, 0x75, 0x65, 0x72, 0x79, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x12, + 0x2c, 0x0a, 0x09, 0x73, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, + 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x2e, 0x53, 0x65, 0x71, 0x75, 0x65, 0x6e, + 0x63, 0x65, 0x52, 0x09, 0x73, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x65, 0x73, 0x22, 0x45, 0x0a, + 0x0e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x4b, 0x65, 0x79, 0x73, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x12, + 0x33, 0x0a, 0x09, 0x73, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, + 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x2e, 0x53, 0x65, 0x71, 0x75, 0x65, 0x6e, + 0x63, 0x65, 0x57, 0x69, 0x74, 0x68, 0x4b, 0x65, 0x79, 0x52, 0x09, 0x73, 0x65, 0x71, 0x75, 0x65, + 0x6e, 0x63, 0x65, 0x73, 0x22, 0x67, 0x0a, 0x0d, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, + 0x42, 0x61, 0x74, 0x63, 0x68, 0x12, 0x2f, 0x0a, 0x08, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, + 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x2e, 0x42, + 0x6f, 0x75, 0x6e, 0x64, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, 0x52, 0x08, 0x63, 0x6f, + 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, 0x12, 0x25, 0x0a, 0x05, 0x72, 0x65, 0x61, 0x64, 0x73, 0x18, + 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x2e, 0x42, 0x61, 0x74, + 0x63, 0x68, 0x52, 0x65, 0x61, 0x64, 0x52, 0x05, 0x72, 0x65, 0x61, 0x64, 0x73, 0x22, 0x8b, 0x01, + 0x0a, 0x09, 0x42, 0x61, 0x74, 0x63, 0x68, 0x52, 0x65, 0x61, 0x64, 0x12, 0x1b, 0x0a, 0x09, 0x72, + 0x65, 0x61, 0x64, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, + 0x72, 0x65, 0x61, 0x64, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x2c, 0x0a, 0x06, 0x70, 0x61, 0x72, 0x61, + 0x6d, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x2e, + 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x64, 0x42, 0x79, 0x74, 0x65, 0x73, 0x52, 0x06, + 0x70, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x12, 0x33, 0x0a, 0x0a, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, + 0x5f, 0x76, 0x61, 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x6c, 0x6f, 0x6f, + 0x70, 0x2e, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x64, 0x42, 0x79, 0x74, 0x65, 0x73, + 0x52, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x56, 0x61, 0x6c, 0x22, 0x77, 0x0a, 0x13, 0x43, + 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, 0x42, 0x61, 0x74, 0x63, 0x68, 0x52, 0x65, 0x73, 0x75, + 0x6c, 0x74, 0x12, 0x2f, 0x0a, 0x08, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x2e, 0x42, 0x6f, 0x75, 0x6e, + 0x64, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, 0x52, 0x08, 0x63, 0x6f, 0x6e, 0x74, 0x72, + 0x61, 0x63, 0x74, 0x12, 0x2f, 0x0a, 0x07, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x18, 0x02, + 0x20, 0x03, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x2e, 0x42, 0x61, 0x74, 0x63, + 0x68, 0x52, 0x65, 0x61, 0x64, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x52, 0x07, 0x72, 0x65, 0x73, + 0x75, 0x6c, 0x74, 0x73, 0x22, 0x79, 0x0a, 0x0f, 0x42, 0x61, 0x74, 0x63, 0x68, 0x52, 0x65, 0x61, + 0x64, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x72, 0x65, 0x61, 0x64, 0x5f, + 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x72, 0x65, 0x61, 0x64, + 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x33, 0x0a, 0x0a, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x5f, 0x76, + 0x61, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x2e, + 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x64, 0x42, 0x79, 0x74, 0x65, 0x73, 0x52, 0x09, + 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x56, 0x61, 0x6c, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x72, 0x72, + 0x6f, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x22, + 0x50, 0x0a, 0x04, 0x48, 0x65, 0x61, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x68, 0x65, 0x69, 0x67, 0x68, + 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x12, + 0x12, 0x0a, 0x04, 0x68, 0x61, 0x73, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x68, + 0x61, 0x73, 0x68, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, + 0x70, 0x22, 0x7d, 0x0a, 0x08, 0x53, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x65, 0x12, 0x27, 0x0a, + 0x0f, 0x73, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x65, 0x5f, 0x63, 0x75, 0x72, 0x73, 0x6f, 0x72, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x73, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x65, + 0x43, 0x75, 0x72, 0x73, 0x6f, 0x72, 0x12, 0x1e, 0x0a, 0x04, 0x68, 0x65, 0x61, 0x64, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0a, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x2e, 0x48, 0x65, 0x61, 0x64, + 0x52, 0x04, 0x68, 0x65, 0x61, 0x64, 0x12, 0x28, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x03, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x2e, 0x56, 0x65, 0x72, 0x73, + 0x69, 0x6f, 0x6e, 0x65, 0x64, 0x42, 0x79, 0x74, 0x65, 0x73, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, + 0x22, 0x96, 0x01, 0x0a, 0x0f, 0x53, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x65, 0x57, 0x69, 0x74, + 0x68, 0x4b, 0x65, 0x79, 0x12, 0x27, 0x0a, 0x0f, 0x73, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x65, + 0x5f, 0x63, 0x75, 0x72, 0x73, 0x6f, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x73, + 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x65, 0x43, 0x75, 0x72, 0x73, 0x6f, 0x72, 0x12, 0x1e, 0x0a, + 0x04, 0x68, 0x65, 0x61, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0a, 0x2e, 0x6c, 0x6f, + 0x6f, 0x70, 0x2e, 0x48, 0x65, 0x61, 0x64, 0x52, 0x04, 0x68, 0x65, 0x61, 0x64, 0x12, 0x28, 0x0a, + 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x6c, 0x6f, + 0x6f, 0x70, 0x2e, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x64, 0x42, 0x79, 0x74, 0x65, + 0x73, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x04, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x22, 0x3d, 0x0a, 0x0d, 0x42, 0x6f, 0x75, + 0x6e, 0x64, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x61, 0x64, + 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x61, 0x64, 0x64, + 0x72, 0x65, 0x73, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x54, 0x0a, 0x0e, 0x51, 0x75, 0x65, 0x72, + 0x79, 0x4b, 0x65, 0x79, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, + 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x30, 0x0a, 0x0a, + 0x65, 0x78, 0x70, 0x72, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, + 0x32, 0x10, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x2e, 0x45, 0x78, 0x70, 0x72, 0x65, 0x73, 0x73, 0x69, + 0x6f, 0x6e, 0x52, 0x0a, 0x65, 0x78, 0x70, 0x72, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0x94, + 0x01, 0x0a, 0x0a, 0x45, 0x78, 0x70, 0x72, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x2f, 0x0a, + 0x09, 0x70, 0x72, 0x69, 0x6d, 0x69, 0x74, 0x69, 0x76, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x0f, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x2e, 0x50, 0x72, 0x69, 0x6d, 0x69, 0x74, 0x69, 0x76, + 0x65, 0x48, 0x00, 0x52, 0x09, 0x70, 0x72, 0x69, 0x6d, 0x69, 0x74, 0x69, 0x76, 0x65, 0x12, 0x48, + 0x0a, 0x12, 0x62, 0x6f, 0x6f, 0x6c, 0x65, 0x61, 0x6e, 0x5f, 0x65, 0x78, 0x70, 0x72, 0x65, 0x73, + 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x6c, 0x6f, 0x6f, + 0x70, 0x2e, 0x42, 0x6f, 0x6f, 0x6c, 0x65, 0x61, 0x6e, 0x45, 0x78, 0x70, 0x72, 0x65, 0x73, 0x73, + 0x69, 0x6f, 0x6e, 0x48, 0x00, 0x52, 0x11, 0x62, 0x6f, 0x6f, 0x6c, 0x65, 0x61, 0x6e, 0x45, 0x78, + 0x70, 0x72, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x42, 0x0b, 0x0a, 0x09, 0x65, 0x76, 0x61, 0x6c, + 0x75, 0x61, 0x74, 0x6f, 0x72, 0x22, 0x87, 0x01, 0x0a, 0x11, 0x42, 0x6f, 0x6f, 0x6c, 0x65, 0x61, + 0x6e, 0x45, 0x78, 0x70, 0x72, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x40, 0x0a, 0x10, 0x62, + 0x6f, 0x6f, 0x6c, 0x65, 0x61, 0x6e, 0x5f, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x15, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x2e, 0x42, 0x6f, 0x6f, + 0x6c, 0x65, 0x61, 0x6e, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x52, 0x0f, 0x62, 0x6f, + 0x6f, 0x6c, 0x65, 0x61, 0x6e, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x12, 0x30, 0x0a, + 0x0a, 0x65, 0x78, 0x70, 0x72, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x03, 0x28, + 0x0b, 0x32, 0x10, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x2e, 0x45, 0x78, 0x70, 0x72, 0x65, 0x73, 0x73, + 0x69, 0x6f, 0x6e, 0x52, 0x0a, 0x65, 0x78, 0x70, 0x72, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x22, + 0x2b, 0x0a, 0x03, 0x41, 0x6e, 0x64, 0x12, 0x24, 0x0a, 0x04, 0x65, 0x78, 0x70, 0x72, 0x18, 0x01, + 0x20, 0x03, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x2e, 0x45, 0x78, 0x70, 0x72, + 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x04, 0x65, 0x78, 0x70, 0x72, 0x22, 0x2a, 0x0a, 0x02, + 0x4f, 0x72, 0x12, 0x24, 0x0a, 0x04, 0x65, 0x78, 0x70, 0x72, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, + 0x32, 0x10, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x2e, 0x45, 0x78, 0x70, 0x72, 0x65, 0x73, 0x73, 0x69, + 0x6f, 0x6e, 0x52, 0x04, 0x65, 0x78, 0x70, 0x72, 0x22, 0x73, 0x0a, 0x0f, 0x56, 0x61, 0x6c, 0x75, + 0x65, 0x43, 0x6f, 0x6d, 0x70, 0x61, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x12, 0x2a, 0x0a, 0x05, 0x76, + 0x61, 0x6c, 0x75, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x6c, 0x6f, 0x6f, + 0x70, 0x2e, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x64, 0x42, 0x79, 0x74, 0x65, 0x73, + 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x34, 0x0a, 0x08, 0x6f, 0x70, 0x65, 0x72, 0x61, + 0x74, 0x6f, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x18, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, + 0x2e, 0x43, 0x6f, 0x6d, 0x70, 0x61, 0x72, 0x69, 0x73, 0x6f, 0x6e, 0x4f, 0x70, 0x65, 0x72, 0x61, + 0x74, 0x6f, 0x72, 0x52, 0x08, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x22, 0x64, 0x0a, + 0x0a, 0x43, 0x6f, 0x6d, 0x70, 0x61, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x12, 0x12, 0x0a, 0x04, 0x6e, + 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, + 0x42, 0x0a, 0x11, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x5f, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x72, 0x61, + 0x74, 0x6f, 0x72, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x6c, 0x6f, 0x6f, + 0x70, 0x2e, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x43, 0x6f, 0x6d, 0x70, 0x61, 0x72, 0x61, 0x74, 0x6f, + 0x72, 0x52, 0x10, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x43, 0x6f, 0x6d, 0x70, 0x61, 0x72, 0x61, 0x74, + 0x6f, 0x72, 0x73, 0x22, 0x60, 0x0a, 0x05, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x12, 0x21, 0x0a, 0x0c, + 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x0b, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x12, + 0x34, 0x0a, 0x08, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x0e, 0x32, 0x18, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x2e, 0x43, 0x6f, 0x6d, 0x70, 0x61, 0x72, 0x69, + 0x73, 0x6f, 0x6e, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x52, 0x08, 0x6f, 0x70, 0x65, + 0x72, 0x61, 0x74, 0x6f, 0x72, 0x22, 0x5f, 0x0a, 0x09, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, + 0x6d, 0x70, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, + 0x12, 0x34, 0x0a, 0x08, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x0e, 0x32, 0x18, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x2e, 0x43, 0x6f, 0x6d, 0x70, 0x61, 0x72, + 0x69, 0x73, 0x6f, 0x6e, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x52, 0x08, 0x6f, 0x70, + 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x22, 0x21, 0x0a, 0x06, 0x54, 0x78, 0x48, 0x61, 0x73, 0x68, + 0x12, 0x17, 0x0a, 0x07, 0x74, 0x78, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x06, 0x74, 0x78, 0x48, 0x61, 0x73, 0x68, 0x22, 0xff, 0x01, 0x0a, 0x09, 0x50, 0x72, + 0x69, 0x6d, 0x69, 0x74, 0x69, 0x76, 0x65, 0x12, 0x32, 0x0a, 0x0a, 0x63, 0x6f, 0x6d, 0x70, 0x61, + 0x72, 0x61, 0x74, 0x6f, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x6c, 0x6f, + 0x6f, 0x70, 0x2e, 0x43, 0x6f, 0x6d, 0x70, 0x61, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x48, 0x00, 0x52, + 0x0a, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x12, 0x23, 0x0a, 0x05, 0x62, + 0x6c, 0x6f, 0x63, 0x6b, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0b, 0x2e, 0x6c, 0x6f, 0x6f, + 0x70, 0x2e, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x48, 0x00, 0x52, 0x05, 0x62, 0x6c, 0x6f, 0x63, 0x6b, + 0x12, 0x32, 0x0a, 0x0a, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x64, 0x65, 0x6e, 0x63, 0x65, 0x18, 0x03, + 0x20, 0x01, 0x28, 0x0e, 0x32, 0x10, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x2e, 0x43, 0x6f, 0x6e, 0x66, + 0x69, 0x64, 0x65, 0x6e, 0x63, 0x65, 0x48, 0x00, 0x52, 0x0a, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x64, + 0x65, 0x6e, 0x63, 0x65, 0x12, 0x2f, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, + 0x70, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x2e, 0x54, + 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x48, 0x00, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, + 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x27, 0x0a, 0x07, 0x74, 0x78, 0x5f, 0x68, 0x61, 0x73, 0x68, + 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x2e, 0x54, 0x78, + 0x48, 0x61, 0x73, 0x68, 0x48, 0x00, 0x52, 0x06, 0x74, 0x78, 0x48, 0x61, 0x73, 0x68, 0x42, 0x0b, + 0x0a, 0x09, 0x70, 0x72, 0x69, 0x6d, 0x69, 0x74, 0x69, 0x76, 0x65, 0x22, 0x8d, 0x01, 0x0a, 0x05, + 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x12, 0x1b, 0x0a, 0x06, 0x63, 0x75, 0x72, 0x73, 0x6f, 0x72, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x06, 0x63, 0x75, 0x72, 0x73, 0x6f, 0x72, 0x88, + 0x01, 0x01, 0x12, 0x38, 0x0a, 0x09, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x15, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x2e, 0x43, 0x75, 0x72, + 0x73, 0x6f, 0x72, 0x44, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x48, 0x01, 0x52, 0x09, + 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x88, 0x01, 0x01, 0x12, 0x14, 0x0a, 0x05, + 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x05, 0x63, 0x6f, 0x75, + 0x6e, 0x74, 0x42, 0x09, 0x0a, 0x07, 0x5f, 0x63, 0x75, 0x72, 0x73, 0x6f, 0x72, 0x42, 0x0c, 0x0a, + 0x0a, 0x5f, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x68, 0x0a, 0x06, 0x53, + 0x6f, 0x72, 0x74, 0x42, 0x79, 0x12, 0x2b, 0x0a, 0x09, 0x73, 0x6f, 0x72, 0x74, 0x5f, 0x74, 0x79, + 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x0e, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x2e, + 0x53, 0x6f, 0x72, 0x74, 0x54, 0x79, 0x70, 0x65, 0x52, 0x08, 0x73, 0x6f, 0x72, 0x74, 0x54, 0x79, + 0x70, 0x65, 0x12, 0x31, 0x0a, 0x09, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x13, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x2e, 0x53, 0x6f, 0x72, + 0x74, 0x44, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x09, 0x64, 0x69, 0x72, 0x65, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x58, 0x0a, 0x0c, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x41, 0x6e, + 0x64, 0x53, 0x6f, 0x72, 0x74, 0x12, 0x25, 0x0a, 0x07, 0x73, 0x6f, 0x72, 0x74, 0x5f, 0x62, 0x79, + 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x2e, 0x53, 0x6f, + 0x72, 0x74, 0x42, 0x79, 0x52, 0x06, 0x73, 0x6f, 0x72, 0x74, 0x42, 0x79, 0x12, 0x21, 0x0a, 0x05, + 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0b, 0x2e, 0x6c, 0x6f, + 0x6f, 0x70, 0x2e, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x52, 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x2a, + 0x47, 0x0a, 0x12, 0x43, 0x6f, 0x6d, 0x70, 0x61, 0x72, 0x69, 0x73, 0x6f, 0x6e, 0x4f, 0x70, 0x65, + 0x72, 0x61, 0x74, 0x6f, 0x72, 0x12, 0x06, 0x0a, 0x02, 0x45, 0x71, 0x10, 0x00, 0x12, 0x07, 0x0a, + 0x03, 0x4e, 0x65, 0x71, 0x10, 0x01, 0x12, 0x06, 0x0a, 0x02, 0x47, 0x74, 0x10, 0x02, 0x12, 0x06, + 0x0a, 0x02, 0x4c, 0x74, 0x10, 0x03, 0x12, 0x07, 0x0a, 0x03, 0x47, 0x74, 0x65, 0x10, 0x04, 0x12, + 0x07, 0x0a, 0x03, 0x4c, 0x74, 0x65, 0x10, 0x05, 0x2a, 0x22, 0x0a, 0x0f, 0x42, 0x6f, 0x6f, 0x6c, + 0x65, 0x61, 0x6e, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x12, 0x07, 0x0a, 0x03, 0x41, + 0x4e, 0x44, 0x10, 0x00, 0x12, 0x06, 0x0a, 0x02, 0x4f, 0x52, 0x10, 0x01, 0x2a, 0x2c, 0x0a, 0x0a, + 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x64, 0x65, 0x6e, 0x63, 0x65, 0x12, 0x0f, 0x0a, 0x0b, 0x55, 0x6e, + 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x72, 0x6d, 0x65, 0x64, 0x10, 0x00, 0x12, 0x0d, 0x0a, 0x09, 0x46, + 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x64, 0x10, 0x01, 0x2a, 0x2f, 0x0a, 0x0f, 0x43, 0x75, + 0x72, 0x73, 0x6f, 0x72, 0x44, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x0d, 0x0a, + 0x09, 0x50, 0x72, 0x65, 0x63, 0x65, 0x64, 0x69, 0x6e, 0x67, 0x10, 0x00, 0x12, 0x0d, 0x0a, 0x09, + 0x46, 0x6f, 0x6c, 0x6c, 0x6f, 0x77, 0x69, 0x6e, 0x67, 0x10, 0x01, 0x2a, 0x22, 0x0a, 0x0d, 0x53, + 0x6f, 0x72, 0x74, 0x44, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x07, 0x0a, 0x03, + 0x41, 0x73, 0x63, 0x10, 0x00, 0x12, 0x08, 0x0a, 0x04, 0x44, 0x65, 0x73, 0x63, 0x10, 0x01, 0x2a, + 0x3e, 0x0a, 0x08, 0x53, 0x6f, 0x72, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x11, 0x0a, 0x0d, 0x53, + 0x6f, 0x72, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x10, 0x00, 0x12, 0x0d, + 0x0a, 0x09, 0x53, 0x6f, 0x72, 0x74, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x10, 0x01, 0x12, 0x10, 0x0a, + 0x0c, 0x53, 0x6f, 0x72, 0x74, 0x53, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x65, 0x10, 0x02, 0x32, + 0x83, 0x04, 0x0a, 0x0e, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, 0x52, 0x65, 0x61, 0x64, + 0x65, 0x72, 0x12, 0x4a, 0x0a, 0x0e, 0x47, 0x65, 0x74, 0x4c, 0x61, 0x74, 0x65, 0x73, 0x74, 0x56, + 0x61, 0x6c, 0x75, 0x65, 0x12, 0x1b, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x2e, 0x47, 0x65, 0x74, 0x4c, + 0x61, 0x74, 0x65, 0x73, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x1a, 0x19, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x2e, 0x47, 0x65, 0x74, 0x4c, 0x61, 0x74, 0x65, + 0x73, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x00, 0x12, 0x62, + 0x0a, 0x1a, 0x47, 0x65, 0x74, 0x4c, 0x61, 0x74, 0x65, 0x73, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, + 0x57, 0x69, 0x74, 0x68, 0x48, 0x65, 0x61, 0x64, 0x44, 0x61, 0x74, 0x61, 0x12, 0x1b, 0x2e, 0x6c, + 0x6f, 0x6f, 0x70, 0x2e, 0x47, 0x65, 0x74, 0x4c, 0x61, 0x74, 0x65, 0x73, 0x74, 0x56, 0x61, 0x6c, + 0x75, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x25, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, + 0x2e, 0x47, 0x65, 0x74, 0x4c, 0x61, 0x74, 0x65, 0x73, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x57, + 0x69, 0x74, 0x68, 0x48, 0x65, 0x61, 0x64, 0x44, 0x61, 0x74, 0x61, 0x52, 0x65, 0x70, 0x6c, 0x79, + 0x22, 0x00, 0x12, 0x5c, 0x0a, 0x14, 0x42, 0x61, 0x74, 0x63, 0x68, 0x47, 0x65, 0x74, 0x4c, 0x61, + 0x74, 0x65, 0x73, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x12, 0x21, 0x2e, 0x6c, 0x6f, 0x6f, + 0x70, 0x2e, 0x42, 0x61, 0x74, 0x63, 0x68, 0x47, 0x65, 0x74, 0x4c, 0x61, 0x74, 0x65, 0x73, 0x74, + 0x56, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f, 0x2e, + 0x6c, 0x6f, 0x6f, 0x70, 0x2e, 0x42, 0x61, 0x74, 0x63, 0x68, 0x47, 0x65, 0x74, 0x4c, 0x61, 0x74, + 0x65, 0x73, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x00, + 0x12, 0x38, 0x0a, 0x08, 0x51, 0x75, 0x65, 0x72, 0x79, 0x4b, 0x65, 0x79, 0x12, 0x15, 0x2e, 0x6c, + 0x6f, 0x6f, 0x70, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x1a, 0x13, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, + 0x4b, 0x65, 0x79, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x00, 0x12, 0x3b, 0x0a, 0x09, 0x51, 0x75, + 0x65, 0x72, 0x79, 0x4b, 0x65, 0x79, 0x73, 0x12, 0x16, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x2e, 0x51, + 0x75, 0x65, 0x72, 0x79, 0x4b, 0x65, 0x79, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x14, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x4b, 0x65, 0x79, 0x73, + 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x00, 0x12, 0x33, 0x0a, 0x04, 0x42, 0x69, 0x6e, 0x64, 0x12, + 0x11, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x2e, 0x42, 0x69, 0x6e, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x00, 0x12, 0x37, 0x0a, 0x06, + 0x55, 0x6e, 0x62, 0x69, 0x6e, 0x64, 0x12, 0x13, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x2e, 0x55, 0x6e, + 0x62, 0x69, 0x6e, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, - 0x70, 0x74, 0x79, 0x22, 0x00, 0x12, 0x37, 0x0a, 0x06, 0x55, 0x6e, 0x62, 0x69, 0x6e, 0x64, 0x12, - 0x13, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x2e, 0x55, 0x6e, 0x62, 0x69, 0x6e, 0x64, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x00, 0x42, 0x43, - 0x5a, 0x41, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x73, 0x6d, 0x61, - 0x72, 0x74, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, 0x6b, 0x69, 0x74, 0x2f, 0x63, 0x68, - 0x61, 0x69, 0x6e, 0x6c, 0x69, 0x6e, 0x6b, 0x2d, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2f, 0x70, - 0x6b, 0x67, 0x2f, 0x6c, 0x6f, 0x6f, 0x70, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, - 0x2f, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x70, 0x74, 0x79, 0x22, 0x00, 0x42, 0x43, 0x5a, 0x41, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, + 0x63, 0x6f, 0x6d, 0x2f, 0x73, 0x6d, 0x61, 0x72, 0x74, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, + 0x74, 0x6b, 0x69, 0x74, 0x2f, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x6c, 0x69, 0x6e, 0x6b, 0x2d, 0x63, + 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x6c, 0x6f, 0x6f, 0x70, 0x2f, 0x69, + 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x33, } var ( @@ -2356,7 +2630,7 @@ func file_contract_reader_proto_rawDescGZIP() []byte { } var file_contract_reader_proto_enumTypes = make([]protoimpl.EnumInfo, 6) -var file_contract_reader_proto_msgTypes = make([]protoimpl.MessageInfo, 30) +var file_contract_reader_proto_msgTypes = make([]protoimpl.MessageInfo, 34) var file_contract_reader_proto_goTypes = []interface{}{ (ComparisonOperator)(0), // 0: loop.ComparisonOperator (BooleanOperator)(0), // 1: loop.BooleanOperator @@ -2367,98 +2641,111 @@ var file_contract_reader_proto_goTypes = []interface{}{ (*GetLatestValueRequest)(nil), // 6: loop.GetLatestValueRequest (*BatchGetLatestValuesRequest)(nil), // 7: loop.BatchGetLatestValuesRequest (*QueryKeyRequest)(nil), // 8: loop.QueryKeyRequest - (*BindRequest)(nil), // 9: loop.BindRequest - (*UnbindRequest)(nil), // 10: loop.UnbindRequest - (*GetLatestValueReply)(nil), // 11: loop.GetLatestValueReply - (*GetLatestValueWithHeadDataReply)(nil), // 12: loop.GetLatestValueWithHeadDataReply - (*BatchGetLatestValuesReply)(nil), // 13: loop.BatchGetLatestValuesReply - (*QueryKeyReply)(nil), // 14: loop.QueryKeyReply - (*ContractBatch)(nil), // 15: loop.ContractBatch - (*BatchRead)(nil), // 16: loop.BatchRead - (*ContractBatchResult)(nil), // 17: loop.ContractBatchResult - (*BatchReadResult)(nil), // 18: loop.BatchReadResult - (*Head)(nil), // 19: loop.Head - (*Sequence)(nil), // 20: loop.Sequence - (*BoundContract)(nil), // 21: loop.BoundContract - (*QueryKeyFilter)(nil), // 22: loop.QueryKeyFilter - (*Expression)(nil), // 23: loop.Expression - (*BooleanExpression)(nil), // 24: loop.BooleanExpression - (*And)(nil), // 25: loop.And - (*Or)(nil), // 26: loop.Or - (*ValueComparator)(nil), // 27: loop.ValueComparator - (*Comparator)(nil), // 28: loop.Comparator - (*Block)(nil), // 29: loop.Block - (*Timestamp)(nil), // 30: loop.Timestamp - (*TxHash)(nil), // 31: loop.TxHash - (*Primitive)(nil), // 32: loop.Primitive - (*Limit)(nil), // 33: loop.Limit - (*SortBy)(nil), // 34: loop.SortBy - (*LimitAndSort)(nil), // 35: loop.LimitAndSort - (*VersionedBytes)(nil), // 36: loop.VersionedBytes - (*emptypb.Empty)(nil), // 37: google.protobuf.Empty + (*QueryKeysRequest)(nil), // 9: loop.QueryKeysRequest + (*ContractKeyFilter)(nil), // 10: loop.ContractKeyFilter + (*BindRequest)(nil), // 11: loop.BindRequest + (*UnbindRequest)(nil), // 12: loop.UnbindRequest + (*GetLatestValueReply)(nil), // 13: loop.GetLatestValueReply + (*GetLatestValueWithHeadDataReply)(nil), // 14: loop.GetLatestValueWithHeadDataReply + (*BatchGetLatestValuesReply)(nil), // 15: loop.BatchGetLatestValuesReply + (*QueryKeyReply)(nil), // 16: loop.QueryKeyReply + (*QueryKeysReply)(nil), // 17: loop.QueryKeysReply + (*ContractBatch)(nil), // 18: loop.ContractBatch + (*BatchRead)(nil), // 19: loop.BatchRead + (*ContractBatchResult)(nil), // 20: loop.ContractBatchResult + (*BatchReadResult)(nil), // 21: loop.BatchReadResult + (*Head)(nil), // 22: loop.Head + (*Sequence)(nil), // 23: loop.Sequence + (*SequenceWithKey)(nil), // 24: loop.SequenceWithKey + (*BoundContract)(nil), // 25: loop.BoundContract + (*QueryKeyFilter)(nil), // 26: loop.QueryKeyFilter + (*Expression)(nil), // 27: loop.Expression + (*BooleanExpression)(nil), // 28: loop.BooleanExpression + (*And)(nil), // 29: loop.And + (*Or)(nil), // 30: loop.Or + (*ValueComparator)(nil), // 31: loop.ValueComparator + (*Comparator)(nil), // 32: loop.Comparator + (*Block)(nil), // 33: loop.Block + (*Timestamp)(nil), // 34: loop.Timestamp + (*TxHash)(nil), // 35: loop.TxHash + (*Primitive)(nil), // 36: loop.Primitive + (*Limit)(nil), // 37: loop.Limit + (*SortBy)(nil), // 38: loop.SortBy + (*LimitAndSort)(nil), // 39: loop.LimitAndSort + (*VersionedBytes)(nil), // 40: loop.VersionedBytes + (*emptypb.Empty)(nil), // 41: google.protobuf.Empty } var file_contract_reader_proto_depIdxs = []int32{ 2, // 0: loop.GetLatestValueRequest.confidence:type_name -> loop.Confidence - 36, // 1: loop.GetLatestValueRequest.params:type_name -> loop.VersionedBytes - 15, // 2: loop.BatchGetLatestValuesRequest.requests:type_name -> loop.ContractBatch - 21, // 3: loop.QueryKeyRequest.contract:type_name -> loop.BoundContract - 22, // 4: loop.QueryKeyRequest.filter:type_name -> loop.QueryKeyFilter - 35, // 5: loop.QueryKeyRequest.limit_and_sort:type_name -> loop.LimitAndSort - 21, // 6: loop.BindRequest.bindings:type_name -> loop.BoundContract - 21, // 7: loop.UnbindRequest.bindings:type_name -> loop.BoundContract - 36, // 8: loop.GetLatestValueReply.ret_val:type_name -> loop.VersionedBytes - 36, // 9: loop.GetLatestValueWithHeadDataReply.ret_val:type_name -> loop.VersionedBytes - 19, // 10: loop.GetLatestValueWithHeadDataReply.head_data:type_name -> loop.Head - 17, // 11: loop.BatchGetLatestValuesReply.results:type_name -> loop.ContractBatchResult - 20, // 12: loop.QueryKeyReply.sequences:type_name -> loop.Sequence - 21, // 13: loop.ContractBatch.contract:type_name -> loop.BoundContract - 16, // 14: loop.ContractBatch.reads:type_name -> loop.BatchRead - 36, // 15: loop.BatchRead.params:type_name -> loop.VersionedBytes - 36, // 16: loop.BatchRead.return_val:type_name -> loop.VersionedBytes - 21, // 17: loop.ContractBatchResult.contract:type_name -> loop.BoundContract - 18, // 18: loop.ContractBatchResult.results:type_name -> loop.BatchReadResult - 36, // 19: loop.BatchReadResult.return_val:type_name -> loop.VersionedBytes - 19, // 20: loop.Sequence.head:type_name -> loop.Head - 36, // 21: loop.Sequence.data:type_name -> loop.VersionedBytes - 23, // 22: loop.QueryKeyFilter.expression:type_name -> loop.Expression - 32, // 23: loop.Expression.primitive:type_name -> loop.Primitive - 24, // 24: loop.Expression.boolean_expression:type_name -> loop.BooleanExpression - 1, // 25: loop.BooleanExpression.boolean_operator:type_name -> loop.BooleanOperator - 23, // 26: loop.BooleanExpression.expression:type_name -> loop.Expression - 23, // 27: loop.And.expr:type_name -> loop.Expression - 23, // 28: loop.Or.expr:type_name -> loop.Expression - 36, // 29: loop.ValueComparator.value:type_name -> loop.VersionedBytes - 0, // 30: loop.ValueComparator.operator:type_name -> loop.ComparisonOperator - 27, // 31: loop.Comparator.value_comparators:type_name -> loop.ValueComparator - 0, // 32: loop.Block.operator:type_name -> loop.ComparisonOperator - 0, // 33: loop.Timestamp.operator:type_name -> loop.ComparisonOperator - 28, // 34: loop.Primitive.comparator:type_name -> loop.Comparator - 29, // 35: loop.Primitive.block:type_name -> loop.Block - 2, // 36: loop.Primitive.confidence:type_name -> loop.Confidence - 30, // 37: loop.Primitive.timestamp:type_name -> loop.Timestamp - 31, // 38: loop.Primitive.tx_hash:type_name -> loop.TxHash - 3, // 39: loop.Limit.direction:type_name -> loop.CursorDirection - 5, // 40: loop.SortBy.sort_type:type_name -> loop.SortType - 4, // 41: loop.SortBy.direction:type_name -> loop.SortDirection - 34, // 42: loop.LimitAndSort.sort_by:type_name -> loop.SortBy - 33, // 43: loop.LimitAndSort.limit:type_name -> loop.Limit - 6, // 44: loop.ContractReader.GetLatestValue:input_type -> loop.GetLatestValueRequest - 6, // 45: loop.ContractReader.GetLatestValueWithHeadData:input_type -> loop.GetLatestValueRequest - 7, // 46: loop.ContractReader.BatchGetLatestValues:input_type -> loop.BatchGetLatestValuesRequest - 8, // 47: loop.ContractReader.QueryKey:input_type -> loop.QueryKeyRequest - 9, // 48: loop.ContractReader.Bind:input_type -> loop.BindRequest - 10, // 49: loop.ContractReader.Unbind:input_type -> loop.UnbindRequest - 11, // 50: loop.ContractReader.GetLatestValue:output_type -> loop.GetLatestValueReply - 12, // 51: loop.ContractReader.GetLatestValueWithHeadData:output_type -> loop.GetLatestValueWithHeadDataReply - 13, // 52: loop.ContractReader.BatchGetLatestValues:output_type -> loop.BatchGetLatestValuesReply - 14, // 53: loop.ContractReader.QueryKey:output_type -> loop.QueryKeyReply - 37, // 54: loop.ContractReader.Bind:output_type -> google.protobuf.Empty - 37, // 55: loop.ContractReader.Unbind:output_type -> google.protobuf.Empty - 50, // [50:56] is the sub-list for method output_type - 44, // [44:50] is the sub-list for method input_type - 44, // [44:44] is the sub-list for extension type_name - 44, // [44:44] is the sub-list for extension extendee - 0, // [0:44] is the sub-list for field type_name + 40, // 1: loop.GetLatestValueRequest.params:type_name -> loop.VersionedBytes + 18, // 2: loop.BatchGetLatestValuesRequest.requests:type_name -> loop.ContractBatch + 25, // 3: loop.QueryKeyRequest.contract:type_name -> loop.BoundContract + 26, // 4: loop.QueryKeyRequest.filter:type_name -> loop.QueryKeyFilter + 39, // 5: loop.QueryKeyRequest.limit_and_sort:type_name -> loop.LimitAndSort + 10, // 6: loop.QueryKeysRequest.filters:type_name -> loop.ContractKeyFilter + 39, // 7: loop.QueryKeysRequest.limit_and_sort:type_name -> loop.LimitAndSort + 25, // 8: loop.ContractKeyFilter.contract:type_name -> loop.BoundContract + 26, // 9: loop.ContractKeyFilter.filter:type_name -> loop.QueryKeyFilter + 25, // 10: loop.BindRequest.bindings:type_name -> loop.BoundContract + 25, // 11: loop.UnbindRequest.bindings:type_name -> loop.BoundContract + 40, // 12: loop.GetLatestValueReply.ret_val:type_name -> loop.VersionedBytes + 40, // 13: loop.GetLatestValueWithHeadDataReply.ret_val:type_name -> loop.VersionedBytes + 22, // 14: loop.GetLatestValueWithHeadDataReply.head_data:type_name -> loop.Head + 20, // 15: loop.BatchGetLatestValuesReply.results:type_name -> loop.ContractBatchResult + 23, // 16: loop.QueryKeyReply.sequences:type_name -> loop.Sequence + 24, // 17: loop.QueryKeysReply.sequences:type_name -> loop.SequenceWithKey + 25, // 18: loop.ContractBatch.contract:type_name -> loop.BoundContract + 19, // 19: loop.ContractBatch.reads:type_name -> loop.BatchRead + 40, // 20: loop.BatchRead.params:type_name -> loop.VersionedBytes + 40, // 21: loop.BatchRead.return_val:type_name -> loop.VersionedBytes + 25, // 22: loop.ContractBatchResult.contract:type_name -> loop.BoundContract + 21, // 23: loop.ContractBatchResult.results:type_name -> loop.BatchReadResult + 40, // 24: loop.BatchReadResult.return_val:type_name -> loop.VersionedBytes + 22, // 25: loop.Sequence.head:type_name -> loop.Head + 40, // 26: loop.Sequence.data:type_name -> loop.VersionedBytes + 22, // 27: loop.SequenceWithKey.head:type_name -> loop.Head + 40, // 28: loop.SequenceWithKey.data:type_name -> loop.VersionedBytes + 27, // 29: loop.QueryKeyFilter.expression:type_name -> loop.Expression + 36, // 30: loop.Expression.primitive:type_name -> loop.Primitive + 28, // 31: loop.Expression.boolean_expression:type_name -> loop.BooleanExpression + 1, // 32: loop.BooleanExpression.boolean_operator:type_name -> loop.BooleanOperator + 27, // 33: loop.BooleanExpression.expression:type_name -> loop.Expression + 27, // 34: loop.And.expr:type_name -> loop.Expression + 27, // 35: loop.Or.expr:type_name -> loop.Expression + 40, // 36: loop.ValueComparator.value:type_name -> loop.VersionedBytes + 0, // 37: loop.ValueComparator.operator:type_name -> loop.ComparisonOperator + 31, // 38: loop.Comparator.value_comparators:type_name -> loop.ValueComparator + 0, // 39: loop.Block.operator:type_name -> loop.ComparisonOperator + 0, // 40: loop.Timestamp.operator:type_name -> loop.ComparisonOperator + 32, // 41: loop.Primitive.comparator:type_name -> loop.Comparator + 33, // 42: loop.Primitive.block:type_name -> loop.Block + 2, // 43: loop.Primitive.confidence:type_name -> loop.Confidence + 34, // 44: loop.Primitive.timestamp:type_name -> loop.Timestamp + 35, // 45: loop.Primitive.tx_hash:type_name -> loop.TxHash + 3, // 46: loop.Limit.direction:type_name -> loop.CursorDirection + 5, // 47: loop.SortBy.sort_type:type_name -> loop.SortType + 4, // 48: loop.SortBy.direction:type_name -> loop.SortDirection + 38, // 49: loop.LimitAndSort.sort_by:type_name -> loop.SortBy + 37, // 50: loop.LimitAndSort.limit:type_name -> loop.Limit + 6, // 51: loop.ContractReader.GetLatestValue:input_type -> loop.GetLatestValueRequest + 6, // 52: loop.ContractReader.GetLatestValueWithHeadData:input_type -> loop.GetLatestValueRequest + 7, // 53: loop.ContractReader.BatchGetLatestValues:input_type -> loop.BatchGetLatestValuesRequest + 8, // 54: loop.ContractReader.QueryKey:input_type -> loop.QueryKeyRequest + 9, // 55: loop.ContractReader.QueryKeys:input_type -> loop.QueryKeysRequest + 11, // 56: loop.ContractReader.Bind:input_type -> loop.BindRequest + 12, // 57: loop.ContractReader.Unbind:input_type -> loop.UnbindRequest + 13, // 58: loop.ContractReader.GetLatestValue:output_type -> loop.GetLatestValueReply + 14, // 59: loop.ContractReader.GetLatestValueWithHeadData:output_type -> loop.GetLatestValueWithHeadDataReply + 15, // 60: loop.ContractReader.BatchGetLatestValues:output_type -> loop.BatchGetLatestValuesReply + 16, // 61: loop.ContractReader.QueryKey:output_type -> loop.QueryKeyReply + 17, // 62: loop.ContractReader.QueryKeys:output_type -> loop.QueryKeysReply + 41, // 63: loop.ContractReader.Bind:output_type -> google.protobuf.Empty + 41, // 64: loop.ContractReader.Unbind:output_type -> google.protobuf.Empty + 58, // [58:65] is the sub-list for method output_type + 51, // [51:58] is the sub-list for method input_type + 51, // [51:51] is the sub-list for extension type_name + 51, // [51:51] is the sub-list for extension extendee + 0, // [0:51] is the sub-list for field type_name } func init() { file_contract_reader_proto_init() } @@ -2505,7 +2792,7 @@ func file_contract_reader_proto_init() { } } file_contract_reader_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*BindRequest); i { + switch v := v.(*QueryKeysRequest); i { case 0: return &v.state case 1: @@ -2517,7 +2804,7 @@ func file_contract_reader_proto_init() { } } file_contract_reader_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*UnbindRequest); i { + switch v := v.(*ContractKeyFilter); i { case 0: return &v.state case 1: @@ -2529,7 +2816,7 @@ func file_contract_reader_proto_init() { } } file_contract_reader_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GetLatestValueReply); i { + switch v := v.(*BindRequest); i { case 0: return &v.state case 1: @@ -2541,7 +2828,7 @@ func file_contract_reader_proto_init() { } } file_contract_reader_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GetLatestValueWithHeadDataReply); i { + switch v := v.(*UnbindRequest); i { case 0: return &v.state case 1: @@ -2553,7 +2840,7 @@ func file_contract_reader_proto_init() { } } file_contract_reader_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*BatchGetLatestValuesReply); i { + switch v := v.(*GetLatestValueReply); i { case 0: return &v.state case 1: @@ -2565,7 +2852,7 @@ func file_contract_reader_proto_init() { } } file_contract_reader_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*QueryKeyReply); i { + switch v := v.(*GetLatestValueWithHeadDataReply); i { case 0: return &v.state case 1: @@ -2577,7 +2864,7 @@ func file_contract_reader_proto_init() { } } file_contract_reader_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ContractBatch); i { + switch v := v.(*BatchGetLatestValuesReply); i { case 0: return &v.state case 1: @@ -2589,7 +2876,7 @@ func file_contract_reader_proto_init() { } } file_contract_reader_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*BatchRead); i { + switch v := v.(*QueryKeyReply); i { case 0: return &v.state case 1: @@ -2601,7 +2888,7 @@ func file_contract_reader_proto_init() { } } file_contract_reader_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ContractBatchResult); i { + switch v := v.(*QueryKeysReply); i { case 0: return &v.state case 1: @@ -2613,7 +2900,7 @@ func file_contract_reader_proto_init() { } } file_contract_reader_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*BatchReadResult); i { + switch v := v.(*ContractBatch); i { case 0: return &v.state case 1: @@ -2625,7 +2912,7 @@ func file_contract_reader_proto_init() { } } file_contract_reader_proto_msgTypes[13].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Head); i { + switch v := v.(*BatchRead); i { case 0: return &v.state case 1: @@ -2637,7 +2924,7 @@ func file_contract_reader_proto_init() { } } file_contract_reader_proto_msgTypes[14].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Sequence); i { + switch v := v.(*ContractBatchResult); i { case 0: return &v.state case 1: @@ -2649,7 +2936,7 @@ func file_contract_reader_proto_init() { } } file_contract_reader_proto_msgTypes[15].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*BoundContract); i { + switch v := v.(*BatchReadResult); i { case 0: return &v.state case 1: @@ -2661,7 +2948,7 @@ func file_contract_reader_proto_init() { } } file_contract_reader_proto_msgTypes[16].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*QueryKeyFilter); i { + switch v := v.(*Head); i { case 0: return &v.state case 1: @@ -2673,7 +2960,7 @@ func file_contract_reader_proto_init() { } } file_contract_reader_proto_msgTypes[17].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Expression); i { + switch v := v.(*Sequence); i { case 0: return &v.state case 1: @@ -2685,7 +2972,7 @@ func file_contract_reader_proto_init() { } } file_contract_reader_proto_msgTypes[18].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*BooleanExpression); i { + switch v := v.(*SequenceWithKey); i { case 0: return &v.state case 1: @@ -2697,7 +2984,7 @@ func file_contract_reader_proto_init() { } } file_contract_reader_proto_msgTypes[19].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*And); i { + switch v := v.(*BoundContract); i { case 0: return &v.state case 1: @@ -2709,7 +2996,7 @@ func file_contract_reader_proto_init() { } } file_contract_reader_proto_msgTypes[20].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Or); i { + switch v := v.(*QueryKeyFilter); i { case 0: return &v.state case 1: @@ -2721,7 +3008,7 @@ func file_contract_reader_proto_init() { } } file_contract_reader_proto_msgTypes[21].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ValueComparator); i { + switch v := v.(*Expression); i { case 0: return &v.state case 1: @@ -2733,7 +3020,7 @@ func file_contract_reader_proto_init() { } } file_contract_reader_proto_msgTypes[22].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Comparator); i { + switch v := v.(*BooleanExpression); i { case 0: return &v.state case 1: @@ -2745,7 +3032,7 @@ func file_contract_reader_proto_init() { } } file_contract_reader_proto_msgTypes[23].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Block); i { + switch v := v.(*And); i { case 0: return &v.state case 1: @@ -2757,7 +3044,7 @@ func file_contract_reader_proto_init() { } } file_contract_reader_proto_msgTypes[24].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Timestamp); i { + switch v := v.(*Or); i { case 0: return &v.state case 1: @@ -2769,7 +3056,7 @@ func file_contract_reader_proto_init() { } } file_contract_reader_proto_msgTypes[25].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*TxHash); i { + switch v := v.(*ValueComparator); i { case 0: return &v.state case 1: @@ -2781,7 +3068,7 @@ func file_contract_reader_proto_init() { } } file_contract_reader_proto_msgTypes[26].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Primitive); i { + switch v := v.(*Comparator); i { case 0: return &v.state case 1: @@ -2793,7 +3080,7 @@ func file_contract_reader_proto_init() { } } file_contract_reader_proto_msgTypes[27].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Limit); i { + switch v := v.(*Block); i { case 0: return &v.state case 1: @@ -2805,7 +3092,7 @@ func file_contract_reader_proto_init() { } } file_contract_reader_proto_msgTypes[28].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*SortBy); i { + switch v := v.(*Timestamp); i { case 0: return &v.state case 1: @@ -2817,6 +3104,54 @@ func file_contract_reader_proto_init() { } } file_contract_reader_proto_msgTypes[29].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*TxHash); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_contract_reader_proto_msgTypes[30].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Primitive); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_contract_reader_proto_msgTypes[31].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Limit); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_contract_reader_proto_msgTypes[32].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*SortBy); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_contract_reader_proto_msgTypes[33].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*LimitAndSort); i { case 0: return &v.state @@ -2829,25 +3164,25 @@ func file_contract_reader_proto_init() { } } } - file_contract_reader_proto_msgTypes[17].OneofWrappers = []interface{}{ + file_contract_reader_proto_msgTypes[21].OneofWrappers = []interface{}{ (*Expression_Primitive)(nil), (*Expression_BooleanExpression)(nil), } - file_contract_reader_proto_msgTypes[26].OneofWrappers = []interface{}{ + file_contract_reader_proto_msgTypes[30].OneofWrappers = []interface{}{ (*Primitive_Comparator)(nil), (*Primitive_Block)(nil), (*Primitive_Confidence)(nil), (*Primitive_Timestamp)(nil), (*Primitive_TxHash)(nil), } - file_contract_reader_proto_msgTypes[27].OneofWrappers = []interface{}{} + file_contract_reader_proto_msgTypes[31].OneofWrappers = []interface{}{} type x struct{} out := protoimpl.TypeBuilder{ File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_contract_reader_proto_rawDesc, NumEnums: 6, - NumMessages: 30, + NumMessages: 34, NumExtensions: 0, NumServices: 1, }, diff --git a/pkg/loop/internal/pb/contract_reader.proto b/pkg/loop/internal/pb/contract_reader.proto index 0205f6a2a..8987c0086 100644 --- a/pkg/loop/internal/pb/contract_reader.proto +++ b/pkg/loop/internal/pb/contract_reader.proto @@ -12,6 +12,7 @@ service ContractReader { rpc GetLatestValueWithHeadData (GetLatestValueRequest) returns (GetLatestValueWithHeadDataReply) {} rpc BatchGetLatestValues (BatchGetLatestValuesRequest) returns (BatchGetLatestValuesReply) {} rpc QueryKey(QueryKeyRequest) returns (QueryKeyReply) {} + rpc QueryKeys(QueryKeysRequest) returns (QueryKeysReply) {} rpc Bind(BindRequest) returns (google.protobuf.Empty) {} rpc Unbind(UnbindRequest) returns (google.protobuf.Empty) {} } @@ -37,6 +38,18 @@ message QueryKeyRequest { bool as_value_type = 4; } +// QueryKeysRequest has arguments for [github.com/smartcontractkit/chainlink-common/pkg/types.ContractReader.QueryKeys]. +message QueryKeysRequest { + repeated ContractKeyFilter filters = 1; + LimitAndSort limit_and_sort = 2; +} + +message ContractKeyFilter { + BoundContract contract = 1; + QueryKeyFilter filter = 2; + bool as_value_type = 4; +} + // BindRequest has arguments for [github.com/smartcontractkit/chainlink-common/pkg/types.ContractReader.Bind]. message BindRequest { repeated BoundContract bindings = 1; @@ -69,6 +82,11 @@ message QueryKeyReply { repeated Sequence sequences = 1; } +// QueryKeysReply has return arguments for [github.com/smartcontractkit/chainlink-common/pkg/types.ContractReader.QueryKeys]. +message QueryKeysReply { + repeated SequenceWithKey sequences = 1; +} + // ContractBatch is gRPC adapter for the BatchGetLatestValuesRequest struct map value [github.com/smartcontractkit/chainlink-common/pkg/types.ContractReader.BatchGetLatestValuesRequest]. message ContractBatch { BoundContract contract = 1; @@ -109,6 +127,13 @@ message Sequence { VersionedBytes data = 3; } +message SequenceWithKey { + string sequence_cursor = 1; + Head head = 2; + VersionedBytes data = 3; + string key = 4; +} + // BoundContract represents a [github.com/smartcontractkit/chainlink-common/pkg/types.BoundContract]. message BoundContract { string address = 1; diff --git a/pkg/loop/internal/pb/contract_reader_grpc.pb.go b/pkg/loop/internal/pb/contract_reader_grpc.pb.go index 1c26fd57a..c8f8d5414 100644 --- a/pkg/loop/internal/pb/contract_reader_grpc.pb.go +++ b/pkg/loop/internal/pb/contract_reader_grpc.pb.go @@ -24,6 +24,7 @@ const ( ContractReader_GetLatestValueWithHeadData_FullMethodName = "/loop.ContractReader/GetLatestValueWithHeadData" ContractReader_BatchGetLatestValues_FullMethodName = "/loop.ContractReader/BatchGetLatestValues" ContractReader_QueryKey_FullMethodName = "/loop.ContractReader/QueryKey" + ContractReader_QueryKeys_FullMethodName = "/loop.ContractReader/QueryKeys" ContractReader_Bind_FullMethodName = "/loop.ContractReader/Bind" ContractReader_Unbind_FullMethodName = "/loop.ContractReader/Unbind" ) @@ -36,6 +37,7 @@ type ContractReaderClient interface { GetLatestValueWithHeadData(ctx context.Context, in *GetLatestValueRequest, opts ...grpc.CallOption) (*GetLatestValueWithHeadDataReply, error) BatchGetLatestValues(ctx context.Context, in *BatchGetLatestValuesRequest, opts ...grpc.CallOption) (*BatchGetLatestValuesReply, error) QueryKey(ctx context.Context, in *QueryKeyRequest, opts ...grpc.CallOption) (*QueryKeyReply, error) + QueryKeys(ctx context.Context, in *QueryKeysRequest, opts ...grpc.CallOption) (*QueryKeysReply, error) Bind(ctx context.Context, in *BindRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) Unbind(ctx context.Context, in *UnbindRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) } @@ -84,6 +86,15 @@ func (c *contractReaderClient) QueryKey(ctx context.Context, in *QueryKeyRequest return out, nil } +func (c *contractReaderClient) QueryKeys(ctx context.Context, in *QueryKeysRequest, opts ...grpc.CallOption) (*QueryKeysReply, error) { + out := new(QueryKeysReply) + err := c.cc.Invoke(ctx, ContractReader_QueryKeys_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + func (c *contractReaderClient) Bind(ctx context.Context, in *BindRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) { out := new(emptypb.Empty) err := c.cc.Invoke(ctx, ContractReader_Bind_FullMethodName, in, out, opts...) @@ -110,6 +121,7 @@ type ContractReaderServer interface { GetLatestValueWithHeadData(context.Context, *GetLatestValueRequest) (*GetLatestValueWithHeadDataReply, error) BatchGetLatestValues(context.Context, *BatchGetLatestValuesRequest) (*BatchGetLatestValuesReply, error) QueryKey(context.Context, *QueryKeyRequest) (*QueryKeyReply, error) + QueryKeys(context.Context, *QueryKeysRequest) (*QueryKeysReply, error) Bind(context.Context, *BindRequest) (*emptypb.Empty, error) Unbind(context.Context, *UnbindRequest) (*emptypb.Empty, error) mustEmbedUnimplementedContractReaderServer() @@ -131,6 +143,9 @@ func (UnimplementedContractReaderServer) BatchGetLatestValues(context.Context, * func (UnimplementedContractReaderServer) QueryKey(context.Context, *QueryKeyRequest) (*QueryKeyReply, error) { return nil, status.Errorf(codes.Unimplemented, "method QueryKey not implemented") } +func (UnimplementedContractReaderServer) QueryKeys(context.Context, *QueryKeysRequest) (*QueryKeysReply, error) { + return nil, status.Errorf(codes.Unimplemented, "method QueryKeys not implemented") +} func (UnimplementedContractReaderServer) Bind(context.Context, *BindRequest) (*emptypb.Empty, error) { return nil, status.Errorf(codes.Unimplemented, "method Bind not implemented") } @@ -222,6 +237,24 @@ func _ContractReader_QueryKey_Handler(srv interface{}, ctx context.Context, dec return interceptor(ctx, in, info, handler) } +func _ContractReader_QueryKeys_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(QueryKeysRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ContractReaderServer).QueryKeys(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: ContractReader_QueryKeys_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ContractReaderServer).QueryKeys(ctx, req.(*QueryKeysRequest)) + } + return interceptor(ctx, in, info, handler) +} + func _ContractReader_Bind_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(BindRequest) if err := dec(in); err != nil { @@ -281,6 +314,10 @@ var ContractReader_ServiceDesc = grpc.ServiceDesc{ MethodName: "QueryKey", Handler: _ContractReader_QueryKey_Handler, }, + { + MethodName: "QueryKeys", + Handler: _ContractReader_QueryKeys_Handler, + }, { MethodName: "Bind", Handler: _ContractReader_Bind_Handler, diff --git a/pkg/loop/internal/relayer/pluginprovider/contractreader/contract_reader.go b/pkg/loop/internal/relayer/pluginprovider/contractreader/contract_reader.go index 44cd9a94f..5b49a7afe 100644 --- a/pkg/loop/internal/relayer/pluginprovider/contractreader/contract_reader.go +++ b/pkg/loop/internal/relayer/pluginprovider/contractreader/contract_reader.go @@ -6,6 +6,7 @@ import ( "encoding/json" "errors" "fmt" + "iter" "reflect" "github.com/fxamacker/cbor/v2" @@ -280,6 +281,43 @@ func (c *Client) QueryKey(ctx context.Context, contract types.BoundContract, fil return convertSequencesFromProto(reply.Sequences, sequenceDataType) } +func (c *Client) QueryKeys(ctx context.Context, keyQueries []types.ContractKeyFilter, limitAndSort query.LimitAndSort) (iter.Seq2[string, types.Sequence], error) { + var filters []*pb.ContractKeyFilter + for _, keyQuery := range keyQueries { + _, asValueType := keyQuery.SequenceDataType.(*values.Value) + contract := convertBoundContractToProto(keyQuery.Contract) + + pbQueryFilter, err := convertQueryFilterToProto(keyQuery.KeyFilter, c.encodeWith) + if err != nil { + return nil, err + } + + filters = append(filters, &pb.ContractKeyFilter{ + Contract: contract, + Filter: pbQueryFilter, + AsValueType: asValueType, + }) + } + + pbLimitAndSort, err := convertLimitAndSortToProto(limitAndSort) + if err != nil { + return nil, err + } + + reply, err := c.grpc.QueryKeys( + ctx, + &pb.QueryKeysRequest{ + Filters: filters, + LimitAndSort: pbLimitAndSort, + }, + ) + if err != nil { + return nil, net.WrapRPCErr(err) + } + + return convertSequencesWithKeyFromProto(reply.Sequences, keyQueries) +} + func (c *Client) Bind(ctx context.Context, bindings []types.BoundContract) error { pbBindings := make([]*pb.BoundContract, len(bindings)) for i, b := range bindings { @@ -462,7 +500,7 @@ func (c *Server) BatchGetLatestValues(ctx context.Context, pbRequest *pb.BatchGe func (c *Server) QueryKey(ctx context.Context, request *pb.QueryKeyRequest) (*pb.QueryKeyReply, error) { contract := convertBoundContractFromProto(request.Contract) - queryFilter, err := convertQueryFiltersFromProto(request, contract, c.impl) + queryFilter, err := convertQueryFiltersFromProto(request.Filter, contract, c.impl) if err != nil { return nil, err } @@ -495,6 +533,46 @@ func (c *Server) QueryKey(ctx context.Context, request *pb.QueryKeyRequest) (*pb return &pb.QueryKeyReply{Sequences: pbSequences}, nil } +func (c *Server) QueryKeys(ctx context.Context, request *pb.QueryKeysRequest) (*pb.QueryKeysReply, error) { + var filters []types.ContractKeyFilter + for _, keyQuery := range request.Filters { + contract := convertBoundContractFromProto(keyQuery.Contract) + + queryFilter, err := convertQueryFiltersFromProto(keyQuery.Filter, contract, c.impl) + if err != nil { + return nil, err + } + + sequenceDataType, err := getContractEncodedType(contract.ReadIdentifier(queryFilter.Key), c.impl, false) + if err != nil { + return nil, err + } + + filters = append(filters, types.ContractKeyFilter{ + Contract: contract, + KeyFilter: queryFilter, + SequenceDataType: sequenceDataType, + }) + } + + limitAndSort, err := convertLimitAndSortFromProto(request.GetLimitAndSort()) + if err != nil { + return nil, err + } + + sequences, err := c.impl.QueryKeys(ctx, filters, limitAndSort) + if err != nil { + return nil, err + } + + pbSequences, err := convertSequencesWithKeyToVersionedBytesProto(sequences, request.Filters, c.encodeWith) + if err != nil { + return nil, err + } + + return &pb.QueryKeysReply{Sequences: pbSequences}, nil +} + func (c *Server) Bind(ctx context.Context, bindings *pb.BindRequest) (*emptypb.Empty, error) { tBindings := make([]types.BoundContract, len(bindings.Bindings)) for i, b := range bindings.Bindings { @@ -758,6 +836,42 @@ func convertSequencesToVersionedBytesProto(sequences []types.Sequence, version E return pbSequences, nil } +func convertSequencesWithKeyToVersionedBytesProto(sequences iter.Seq2[string, types.Sequence], filters []*pb.ContractKeyFilter, encodeWith EncodingVersion) ([]*pb.SequenceWithKey, error) { + keyToEncodingVersion := make(map[string]EncodingVersion) + for _, filter := range filters { + if filter.AsValueType { + keyToEncodingVersion[filter.Filter.Key] = ValuesEncodingVersion + } else { + keyToEncodingVersion[filter.Filter.Key] = encodeWith + } + } + + var pbSequences []*pb.SequenceWithKey + for key, sequence := range sequences { + version, ok := keyToEncodingVersion[key] + if !ok { + return nil, fmt.Errorf("missing encoding version for key %s", key) + } + + versionedSequenceDataType, err := EncodeVersionedBytes(sequence.Data, version) + if err != nil { + return nil, err + } + pbSequence := &pb.SequenceWithKey{ + Key: key, + SequenceCursor: sequence.Cursor, + Head: &pb.Head{ + Height: sequence.Height, + Hash: sequence.Hash, + Timestamp: sequence.Timestamp, + }, + Data: versionedSequenceDataType, + } + pbSequences = append(pbSequences, pbSequence) + } + return pbSequences, nil +} + func parseBatchGetLatestValuesReply(request types.BatchGetLatestValuesRequest, reply *pb.BatchGetLatestValuesReply) (types.BatchGetLatestValuesResult, error) { if reply == nil { return nil, fmt.Errorf("received nil reply from grpc BatchGetLatestValues") @@ -844,8 +958,7 @@ func convertBoundContractFromProto(contract *pb.BoundContract) types.BoundContra } } -func convertQueryFiltersFromProto(request *pb.QueryKeyRequest, contract types.BoundContract, impl types.ContractReader) (query.KeyFilter, error) { - pbQueryFilters := request.Filter +func convertQueryFiltersFromProto(pbQueryFilters *pb.QueryKeyFilter, contract types.BoundContract, impl types.ContractReader) (query.KeyFilter, error) { queryFilter := query.KeyFilter{Key: pbQueryFilters.Key} for _, pbQueryFilter := range pbQueryFilters.Expression { expression, err := convertExpressionFromProto(pbQueryFilter, contract, queryFilter.Key, impl) @@ -949,16 +1062,9 @@ func convertLimitAndSortFromProto(limitAndSort *pb.LimitAndSort) (query.LimitAnd func convertSequencesFromProto(pbSequences []*pb.Sequence, sequenceDataType any) ([]types.Sequence, error) { sequences := make([]types.Sequence, len(pbSequences)) - seqTypeOf := reflect.TypeOf(sequenceDataType) - - // get the non-pointer data type for the sequence data - nonPointerType := seqTypeOf - if seqTypeOf.Kind() == reflect.Pointer { - nonPointerType = seqTypeOf.Elem() - } - - if nonPointerType.Kind() == reflect.Pointer { - return nil, fmt.Errorf("%w: sequenceDataType does not support pointers to pointers", types.ErrInvalidType) + seqTypeOf, nonPointerType, err := getSequenceTypeInformation(sequenceDataType) + if err != nil { + return nil, err } for idx, pbSequence := range pbSequences { @@ -986,6 +1092,78 @@ func convertSequencesFromProto(pbSequences []*pb.Sequence, sequenceDataType any) return sequences, nil } +func getSequenceTypeInformation(sequenceDataType any) (reflect.Type, reflect.Type, error) { + seqTypeOf := reflect.TypeOf(sequenceDataType) + + // get the non-pointer data type for the sequence data + nonPointerType := seqTypeOf + if seqTypeOf.Kind() == reflect.Pointer { + nonPointerType = seqTypeOf.Elem() + } + + if nonPointerType.Kind() == reflect.Pointer { + return nil, nil, fmt.Errorf("%w: sequenceDataType does not support pointers to pointers", types.ErrInvalidType) + } + return seqTypeOf, nonPointerType, nil +} + +func convertSequencesWithKeyFromProto(pbSequences []*pb.SequenceWithKey, keyQueries []types.ContractKeyFilter) (iter.Seq2[string, types.Sequence], error) { + type sequenceWithKey struct { + Key string + Sequence types.Sequence + } + + sequencesWithKey := make([]sequenceWithKey, len(pbSequences)) + + keyToSeqTypeOf := make(map[string]reflect.Type) + keyToNonPointerType := make(map[string]reflect.Type) + + for _, keyQuery := range keyQueries { + seqTypeOf, nonPointerType, err := getSequenceTypeInformation(keyQuery.SequenceDataType) + if err != nil { + return nil, err + } + + keyToSeqTypeOf[keyQuery.Key] = seqTypeOf + keyToNonPointerType[keyQuery.Key] = nonPointerType + } + + for idx, pbSequence := range pbSequences { + seqTypeOf, nonPointerType := keyToSeqTypeOf[pbSequence.Key], keyToNonPointerType[pbSequence.Key] + + cpy := reflect.New(nonPointerType).Interface() + if err := DecodeVersionedBytes(cpy, pbSequence.Data); err != nil { + return nil, err + } + + // match provided data type either as pointer or non-pointer + if seqTypeOf.Kind() != reflect.Pointer { + cpy = reflect.Indirect(reflect.ValueOf(cpy)).Interface() + } + pbSeq := pbSequences[idx] + sequencesWithKey[idx] = sequenceWithKey{ + Key: pbSeq.Key, + Sequence: types.Sequence{ + Cursor: pbSeq.SequenceCursor, + Head: types.Head{ + Height: pbSeq.Head.Height, + Hash: pbSeq.Head.Hash, + Timestamp: pbSeq.Head.Timestamp, + }, + Data: cpy, + }, + } + } + + return func(yield func(string, types.Sequence) bool) { + for _, s := range sequencesWithKey { + if !yield(s.Key, s.Sequence) { + return + } + } + }, nil +} + func RegisterContractReaderService(s *grpc.Server, contractReader types.ContractReader) { service := goplugin.ServiceServer{Srv: contractReader} pb.RegisterServiceServer(s, &service) diff --git a/pkg/loop/internal/relayer/pluginprovider/contractreader/contract_reader_test.go b/pkg/loop/internal/relayer/pluginprovider/contractreader/contract_reader_test.go index 0ba463c44..88a87031c 100644 --- a/pkg/loop/internal/relayer/pluginprovider/contractreader/contract_reader_test.go +++ b/pkg/loop/internal/relayer/pluginprovider/contractreader/contract_reader_test.go @@ -4,6 +4,7 @@ import ( "context" "errors" "fmt" + "iter" "math/big" "reflect" "sort" @@ -29,7 +30,7 @@ import ( "github.com/smartcontractkit/chainlink-common/pkg/utils/tests" "github.com/smartcontractkit/chainlink-common/pkg/values" - . "github.com/smartcontractkit/chainlink-common/pkg/types/interfacetests" //nolint + . "github.com/smartcontractkit/chainlink-common/pkg/types/interfacetests" ) func TestVersionedBytesFunctions(t *testing.T) { @@ -306,7 +307,7 @@ func (it *fakeContractReaderInterfaceTester) Setup(_ *testing.T) { fake, ok := it.impl.(*fakeContractReader) if ok { fake.vals = make(map[string][]valConfidencePair) - fake.triggers = make(map[string][]eventConfidencePair) + fake.triggers = newEventsRecorder() fake.stored = make(map[string][]TestStruct) } } @@ -351,11 +352,84 @@ type eventConfidencePair struct { confidenceLevel primitives.ConfidenceLevel } +type dynamicTopicEventConfidencePair struct { + someDynamicTopicEvent SomeDynamicTopicEvent + confidenceLevel primitives.ConfidenceLevel +} +type event struct { + contractID string + event any + confidenceLevel primitives.ConfidenceLevel + eventType string +} + +type eventsRecorder struct { + mux sync.Mutex + events []event +} + +func newEventsRecorder() *eventsRecorder { + return &eventsRecorder{} +} + +func (e *eventsRecorder) RecordEvent(contractID string, evt any, confidenceLevel primitives.ConfidenceLevel, eventType string) error { + e.mux.Lock() + defer e.mux.Unlock() + + switch eventType { + case EventName: + _, ok := evt.(TestStruct) + if !ok { + return fmt.Errorf("unexpected event type %T", evt) + } + case DynamicTopicEventName: + _, ok := evt.(SomeDynamicTopicEvent) + if !ok { + return fmt.Errorf("unexpected event type %T", evt) + } + + } + + e.events = append(e.events, event{contractID: contractID, event: evt, confidenceLevel: confidenceLevel, eventType: eventType}) + + return nil +} + +func (e *eventsRecorder) setConfidenceLevelOnAllEvents(confidenceLevel primitives.ConfidenceLevel) { + e.mux.Lock() + defer e.mux.Unlock() + + for i := range e.events { + e.events[i].confidenceLevel = confidenceLevel + } +} + +func (e *eventsRecorder) getEvents(filters ...func(event) bool) []event { + e.mux.Lock() + defer e.mux.Unlock() + + events := make([]event, 0) + for _, event := range e.events { + match := true + for _, filter := range filters { + if !filter(event) { + match = false + break + } + } + if match { + events = append(events, event) + } + } + + return events +} + type fakeContractReader struct { types.UnimplementedContractReader fakeTypeProvider vals map[string][]valConfidencePair - triggers map[string][]eventConfidencePair + triggers *eventsRecorder stored map[string][]TestStruct batchStored BatchCallEntry lock sync.Mutex @@ -382,11 +456,13 @@ func (f *fakeContractWriter) SubmitTransaction(_ context.Context, contractName, } f.cr.SetUintLatestValue(contractID, v.Value, ExpectedGetLatestValueArgs{}) case MethodTriggeringEvent: - v, ok := args.(TestStruct) - if !ok { - return fmt.Errorf("unexpected type %T", args) + if err := f.cr.triggers.RecordEvent(contractID, args, primitives.Unconfirmed, EventName); err != nil { + return fmt.Errorf("failed to record event: %w", err) + } + case MethodTriggeringEventWithDynamicTopic: + if err := f.cr.triggers.RecordEvent(contractID, args, primitives.Unconfirmed, DynamicTopicEventName); err != nil { + return fmt.Errorf("failed to record event: %w", err) } - f.cr.SetTrigger(contractID, &v) case "batchContractWrite": v, ok := args.(BatchCallEntry) if !ok { @@ -495,14 +571,17 @@ func (f *fakeContractReader) GetLatestValue(_ context.Context, readIdentifier st f.lock.Lock() defer f.lock.Unlock() - triggers := f.triggers[contractName] - if len(triggers) == 0 { + events := f.triggers.getEvents(func(e event) bool { + return e.contractID == contractName && e.eventType == EventName + }) + + if len(events) == 0 { return types.ErrNotFound } - for i := len(triggers) - 1; i >= 0; i-- { - if triggers[i].confidenceLevel == confidenceLevel { - *returnVal.(*TestStruct) = triggers[i].testStruct + for i := len(events) - 1; i >= 0; i-- { + if events[i].confidenceLevel == confidenceLevel { + *returnVal.(*TestStruct) = events[i].event.(TestStruct) return nil } } @@ -512,14 +591,33 @@ func (f *fakeContractReader) GetLatestValue(_ context.Context, readIdentifier st f.lock.Lock() defer f.lock.Unlock() param := params.(*FilterEventParams) - triggers := f.triggers[contractName] + triggers := f.triggers.getEvents(func(e event) bool { return e.contractID == contractName && e.eventType == EventName }) for i := len(triggers) - 1; i >= 0; i-- { - if *triggers[i].testStruct.Field == param.Field { - *returnVal.(*TestStruct) = triggers[i].testStruct + testStruct := triggers[i].event.(TestStruct) + if *testStruct.Field == param.Field { + *returnVal.(*TestStruct) = testStruct return nil } } return types.ErrNotFound + } else if strings.HasSuffix(readIdentifier, DynamicTopicEventName) { + f.lock.Lock() + defer f.lock.Unlock() + + triggers := f.triggers.getEvents(func(e event) bool { return e.contractID == contractName && e.eventType == DynamicTopicEventName }) + + if len(triggers) == 0 { + return types.ErrNotFound + } + + for i := len(triggers) - 1; i >= 0; i-- { + if triggers[i].confidenceLevel == confidenceLevel { + *returnVal.(*SomeDynamicTopicEvent) = triggers[i].event.(SomeDynamicTopicEvent) + return nil + } + } + + return fmt.Errorf("%w: no event with %s confidence was found ", types.ErrNotFound, confidenceLevel) } else if !strings.HasSuffix(readIdentifier, MethodTakingLatestParamsReturningTestStruct) { return errors.New("unknown method " + readIdentifier) } @@ -614,112 +712,166 @@ func (f *fakeContractReader) BatchGetLatestValues(_ context.Context, request typ return result, nil } -func (f *fakeContractReader) QueryKey(_ context.Context, bc types.BoundContract, filter query.KeyFilter, limitAndSort query.LimitAndSort, sequenceType any) ([]types.Sequence, error) { - _, isValueType := sequenceType.(*values.Value) - if filter.Key == EventName { - f.lock.Lock() - defer f.lock.Unlock() - if len(f.triggers) == 0 { - return []types.Sequence{}, nil +func (f *fakeContractReader) QueryKey(ctx context.Context, bc types.BoundContract, filter query.KeyFilter, limitAndSort query.LimitAndSort, sequenceType any) ([]types.Sequence, error) { + seqsIter, err := f.QueryKeys(ctx, []types.ContractKeyFilter{types.ContractKeyFilter{ + KeyFilter: filter, + Contract: bc, + SequenceDataType: sequenceType, + }}, limitAndSort) + + if err != nil { + return nil, err + } + + if seqsIter != nil { + var seqs []types.Sequence + for _, seq := range seqsIter { + seqs = append(seqs, seq) } - var sequences []types.Sequence - for idx, trigger := range f.triggers[bc.String()] { - doAppend := true - for _, expr := range filter.Expressions { - if primitive, ok := expr.Primitive.(*primitives.Comparator); ok { - if len(primitive.ValueComparators) == 0 { - return nil, fmt.Errorf("value comparator for %s should not be empty", primitive.Name) - } - if primitive.Name == "Field" { - for _, valComp := range primitive.ValueComparators { - doAppend = doAppend && Compare(*trigger.testStruct.Field, *valComp.Value.(*int32), valComp.Operator) - } + return seqs, nil + } + + return nil, nil +} + +type sequenceWithEventType struct { + eventType string + sequence types.Sequence +} + +func (f *fakeContractReader) QueryKeys(_ context.Context, filters []types.ContractKeyFilter, limitAndSort query.LimitAndSort) (iter.Seq2[string, types.Sequence], error) { + f.lock.Lock() + defer f.lock.Unlock() + + supportedEventTypes := map[string]struct{}{EventName: {}, DynamicTopicEventName: {}} + + for _, filter := range filters { + if _, ok := supportedEventTypes[filter.Key]; !ok { + return nil, fmt.Errorf("unsupported event type %s", filter.Key) + } + } + + if len(filters) > 1 { + fmt.Printf("filters: %v\n", filters) + } + + isValueType := false + eventTypeToFilter := map[string]types.ContractKeyFilter{} + for _, filter := range filters { + eventTypeToFilter[filter.Key] = filter + _, isValueType = filter.SequenceDataType.(*values.Value) + } + + events := f.triggers.getEvents(func(e event) bool { + filter := eventTypeToFilter[e.eventType] + + if e.contractID != filter.Contract.String() { + return false + } + _, filterExistsForType := eventTypeToFilter[e.eventType] + + return filterExistsForType + }) + + var sequences []sequenceWithEventType + for idx, trigger := range events { + filter := eventTypeToFilter[trigger.eventType] + + doAppend := true + for _, expr := range filter.Expressions { + if primitive, ok := expr.Primitive.(*primitives.Comparator); ok { + if len(primitive.ValueComparators) == 0 { + return nil, fmt.Errorf("value comparator for %s should not be empty", primitive.Name) + } + if primitive.Name == "Field" { + for _, valComp := range primitive.ValueComparators { + doAppend = doAppend && Compare(*trigger.event.(TestStruct).Field, *valComp.Value.(*int32), valComp.Operator) } } } + } - var skipAppend bool - if limitAndSort.HasCursorLimit() { - cursor, err := strconv.Atoi(limitAndSort.Limit.Cursor) - if err != nil { - return nil, err - } + var skipAppend bool + if limitAndSort.HasCursorLimit() { + cursor, err := strconv.Atoi(limitAndSort.Limit.Cursor) + if err != nil { + return nil, err + } - // assume CursorFollowing order for now - if cursor >= idx { - skipAppend = true - } + // assume CursorFollowing order for now + if cursor >= idx { + skipAppend = true } + } - if (len(filter.Expressions) == 0 || doAppend) && !skipAppend { - if isValueType { - value, err := values.Wrap(trigger.testStruct) - if err != nil { - return nil, err - } - sequences = append(sequences, types.Sequence{Cursor: strconv.Itoa(idx), Data: &value}) - } else { - sequences = append(sequences, types.Sequence{Cursor: fmt.Sprintf("%d", idx), Data: trigger.testStruct}) + if (len(eventTypeToFilter[trigger.eventType].Expressions) == 0 || doAppend) && !skipAppend { + if isValueType { + value, err := values.Wrap(trigger.event) + if err != nil { + return nil, err } + sequences = append(sequences, sequenceWithEventType{eventType: trigger.eventType, sequence: types.Sequence{Cursor: strconv.Itoa(idx), Data: &value}}) + } else { + sequences = append(sequences, sequenceWithEventType{eventType: trigger.eventType, sequence: types.Sequence{Cursor: fmt.Sprintf("%d", idx), Data: trigger.event}}) } + } - if limitAndSort.Limit.Count > 0 && len(sequences) >= int(limitAndSort.Limit.Count) { - break - } + if limitAndSort.Limit.Count > 0 && len(sequences) >= int(limitAndSort.Limit.Count) { + break } + } - if isValueType { - if !limitAndSort.HasSequenceSort() && !limitAndSort.HasCursorLimit() { - sort.Slice(sequences, func(i, j int) bool { - valI := *sequences[i].Data.(*values.Value) - valJ := *sequences[j].Data.(*values.Value) + if isValueType { + if !limitAndSort.HasSequenceSort() && !limitAndSort.HasCursorLimit() { + sort.Slice(sequences, func(i, j int) bool { + valI := *sequences[i].sequence.Data.(*values.Value) + valJ := *sequences[j].sequence.Data.(*values.Value) - mapI := valI.(*values.Map) - mapJ := valJ.(*values.Map) + mapI := valI.(*values.Map) + mapJ := valJ.(*values.Map) - if mapI.Underlying["Field"] == nil || mapJ.Underlying["Field"] == nil { - return false - } - var iVal int32 - err := mapI.Underlying["Field"].UnwrapTo(&iVal) - if err != nil { - panic(err) - } + if mapI.Underlying["Field"] == nil || mapJ.Underlying["Field"] == nil { + return false + } + var iVal int32 + err := mapI.Underlying["Field"].UnwrapTo(&iVal) + if err != nil { + panic(err) + } - var jVal int32 - err = mapJ.Underlying["Field"].UnwrapTo(&jVal) - if err != nil { - panic(err) - } + var jVal int32 + err = mapJ.Underlying["Field"].UnwrapTo(&jVal) + if err != nil { + panic(err) + } - return iVal > jVal - }) - } - } else { - if !limitAndSort.HasSequenceSort() && !limitAndSort.HasCursorLimit() { - sort.Slice(sequences, func(i, j int) bool { - if sequences[i].Data.(TestStruct).Field == nil || sequences[j].Data.(TestStruct).Field == nil { - return false - } - return *sequences[i].Data.(TestStruct).Field > *sequences[j].Data.(TestStruct).Field - }) + return iVal > jVal + }) + } + } else { + if !limitAndSort.HasSequenceSort() && !limitAndSort.HasCursorLimit() { + if len(eventTypeToFilter) == 1 { + if _, ok := eventTypeToFilter[EventName]; ok { + sort.Slice(sequences, func(i, j int) bool { + if sequences[i].sequence.Data.(TestStruct).Field == nil || sequences[j].sequence.Data.(TestStruct).Field == nil { + return false + } + return *sequences[i].sequence.Data.(TestStruct).Field > *sequences[j].sequence.Data.(TestStruct).Field + }) + } } } - - return sequences, nil } - return nil, nil -} -func (f *fakeContractReader) SetTrigger(contractID string, testStruct *TestStruct) { - f.lock.Lock() - defer f.lock.Unlock() - if _, ok := f.triggers[contractID]; !ok { - f.triggers[contractID] = []eventConfidencePair{} - } + return func(yield func(string, types.Sequence) bool) { + for _, s := range sequences { + if !yield(s.eventType, s.sequence) { + return + } + } + }, nil - f.triggers[contractID] = append(f.triggers[contractID], eventConfidencePair{testStruct: *testStruct, confidenceLevel: primitives.Unconfirmed}) } func (f *fakeContractReader) GenerateBlocksTillConfidenceLevel(_ *testing.T, _, _ string, confidenceLevel primitives.ConfidenceLevel) { @@ -732,11 +884,7 @@ func (f *fakeContractReader) GenerateBlocksTillConfidenceLevel(_ *testing.T, _, } } - for contractID, triggers := range f.triggers { - for i, trigger := range triggers { - f.triggers[contractID][i] = eventConfidencePair{testStruct: trigger.testStruct, confidenceLevel: confidenceLevel} - } - } + f.triggers.setConfidenceLevelOnAllEvents(confidenceLevel) } type errContractReader struct { diff --git a/pkg/loop/internal/relayer/pluginprovider/contractreader/helper_test.go b/pkg/loop/internal/relayer/pluginprovider/contractreader/helper_test.go index 9d87f581c..aa66b4edb 100644 --- a/pkg/loop/internal/relayer/pluginprovider/contractreader/helper_test.go +++ b/pkg/loop/internal/relayer/pluginprovider/contractreader/helper_test.go @@ -99,6 +99,11 @@ func (fakeTypeProvider) CreateContractType(readName string, isEncode bool) (any, return &FilterEventParams{}, nil } return &TestStruct{}, nil + case strings.HasSuffix(readName, DynamicTopicEventName), strings.HasSuffix(readName, EventWithFilterName): + if isEncode { + return &FilterEventParams{}, nil + } + return &SomeDynamicTopicEvent{}, nil case strings.HasSuffix(readName, EventNameField): if isEncode { var typ int32 diff --git a/pkg/types/contract_reader.go b/pkg/types/contract_reader.go index 9cf6b0555..206e77ae4 100644 --- a/pkg/types/contract_reader.go +++ b/pkg/types/contract_reader.go @@ -2,6 +2,7 @@ package types import ( "context" + "iter" "github.com/smartcontractkit/chainlink-common/pkg/services" "github.com/smartcontractkit/chainlink-common/pkg/types/query" @@ -65,9 +66,19 @@ type ContractReader interface { // QueryKey provides fetching chain agnostic events (Sequence) with general querying capability. QueryKey(ctx context.Context, contract BoundContract, filter query.KeyFilter, limitAndSort query.LimitAndSort, sequenceDataType any) ([]Sequence, error) + // QueryKeys provides fetching chain agnostic events (Sequence) of different types with general querying capability. + // The iterator returns a pair of key and sequence. + QueryKeys(ctx context.Context, filters []ContractKeyFilter, limitAndSort query.LimitAndSort) (iter.Seq2[string, Sequence], error) + mustEmbedUnimplementedContractReader() } +type ContractKeyFilter struct { + query.KeyFilter + Contract BoundContract + SequenceDataType any +} + // BatchGetLatestValuesRequest string is contract name. type BatchGetLatestValuesRequest map[BoundContract]ContractBatch type ContractBatch []BatchRead @@ -153,6 +164,10 @@ func (UnimplementedContractReader) QueryKey(ctx context.Context, boundContract B return nil, UnimplementedError("ContractReader.QueryKey unimplemented") } +func (UnimplementedContractReader) QueryKeys(ctx context.Context, keyQueries []ContractKeyFilter, limitAndSort query.LimitAndSort) (iter.Seq2[string, Sequence], error) { + return nil, UnimplementedError("ContractReader.QueryKeys unimplemented") +} + func (UnimplementedContractReader) Start(context.Context) error { return UnimplementedError("ContractReader.Start unimplemented") } diff --git a/pkg/types/interfacetests/chain_components_interface_tests.go b/pkg/types/interfacetests/chain_components_interface_tests.go index 1c1e9a001..7d32471ce 100644 --- a/pkg/types/interfacetests/chain_components_interface_tests.go +++ b/pkg/types/interfacetests/chain_components_interface_tests.go @@ -59,6 +59,16 @@ const ( ContractReaderQueryKeyCanLimitResultsWithCursor = "QueryKey can limit results with cursor" ) +// Query keys +const ( + ContractReaderQueryKeysReturnsDataTwoEventTypes = "QueryKeys returns sequence data properly for two event types" + ContractReaderQueryKeysNotFound = "QueryKeys returns not found if sequence never happened" + ContractReaderQueryKeysReturnsData = "QueryKeys returns sequence data properly" + ContractReaderQueryKeysReturnsDataAsValuesDotValue = "QueryKeys returns sequence data properly as values.Value" + ContractReaderQueryKeysCanFilterWithValueComparator = "QueryKeys can filter data with value comparator" + ContractReaderQueryKeysCanLimitResultsWithCursor = "QueryKeys can limit results with cursor" +) + type ChainComponentsInterfaceTester[T TestingT[T]] interface { BasicTester[T] GetContractReader(t T) types.ContractReader @@ -85,6 +95,8 @@ const ( MethodSettingStruct = "addTestStruct" MethodSettingUint64 = "setAlterablePrimitiveValue" MethodTriggeringEvent = "triggerEvent" + MethodTriggeringEventWithDynamicTopic = "triggerEventWithDynamicTopic" + DynamicTopicEventName = "TriggeredEventWithDynamicTopic" EventName = "SomeEvent" EventNameField = EventName + ".Field" ProtoTest = "ProtoTest" @@ -104,11 +116,336 @@ func RunContractReaderInterfaceTests[T TestingT[T]](t T, tester ChainComponentsI t.Run("GetLatestValue", func(t T) { runContractReaderGetLatestValueInterfaceTests(t, tester, mockRun) }) t.Run("BatchGetLatestValues", func(t T) { runContractReaderBatchGetLatestValuesInterfaceTests(t, tester, mockRun) }) t.Run("QueryKey", func(t T) { runQueryKeyInterfaceTests(t, tester) }) + t.Run("QueryKeys", func(t T) { runQueryKeysInterfaceTests(t, tester) }) }) } -func runContractReaderGetLatestValueInterfaceTests[T TestingT[T]](t T, tester ChainComponentsInterfaceTester[T], mockRun bool) { +type SomeDynamicTopicEvent struct { + Field string +} + +type sequenceWithKey struct { + types.Sequence + Key string +} + +func runQueryKeysInterfaceTests[T TestingT[T]](t T, tester ChainComponentsInterfaceTester[T]) { + tests := []Testcase[T]{ + { + Name: ContractReaderQueryKeysReturnsDataTwoEventTypes, + Test: func(t T) { + ctx := tests.Context(t) + cr := tester.GetContractReader(t) + bindings := tester.GetBindings(t) + + require.NoError(t, cr.Bind(ctx, bindings)) + boundContract := BindingsByName(bindings, AnyContractName)[0] + + expectedSequenceData := createMixedEventTypeSequence(t, tester, boundContract) + + ts := &TestStruct{} + require.Eventually(t, func() bool { + contractFilter := types.ContractKeyFilter{ + Contract: boundContract, + KeyFilter: query.KeyFilter{Key: EventName}, + SequenceDataType: ts, + } + + ds := SomeDynamicTopicEvent{} + secondContractFilter := types.ContractKeyFilter{ + Contract: boundContract, + KeyFilter: query.KeyFilter{Key: DynamicTopicEventName}, + SequenceDataType: &ds, + } + + sequencesIter, err := cr.QueryKeys(ctx, []types.ContractKeyFilter{secondContractFilter, contractFilter}, query.LimitAndSort{}) + if err != nil { + return false + } + + sequences := make([]sequenceWithKey, 0) + for k, s := range sequencesIter { + sequences = append(sequences, sequenceWithKey{Sequence: s, Key: k}) + } + + return sequenceDataEqual(expectedSequenceData, sequences) + }, tester.MaxWaitTimeForEvents(), time.Millisecond*10) + }, + }, + + { + Name: ContractReaderQueryKeysNotFound, + Test: func(t T) { + ctx := tests.Context(t) + cr := tester.GetContractReader(t) + bindings := tester.GetBindings(t) + bound := BindingsByName(bindings, AnyContractName)[0] + + require.NoError(t, cr.Bind(ctx, tester.GetBindings(t))) + + contractFilter := types.ContractKeyFilter{ + Contract: bound, + KeyFilter: query.KeyFilter{Key: EventName}, + SequenceDataType: &TestStruct{}, + } + + logsIter, err := cr.QueryKeys(ctx, []types.ContractKeyFilter{contractFilter}, query.LimitAndSort{}) + require.NoError(t, err) + var logs []types.Sequence + for _, log := range logsIter { + logs = append(logs, log) + } + assert.Len(t, logs, 0) + }, + }, + + { + Name: ContractReaderQueryKeysReturnsDataAsValuesDotValue, + Test: func(t T) { + ctx := tests.Context(t) + cr := tester.GetContractReader(t) + bindings := tester.GetBindings(t) + + require.NoError(t, cr.Bind(ctx, bindings)) + bound := BindingsByName(bindings, AnyContractName)[0] + + expectedSequenceData := createMixedEventTypeSequence(t, tester, bound) + + var value values.Value + require.Eventually(t, func() bool { + contractFilter := types.ContractKeyFilter{ + Contract: bound, + KeyFilter: query.KeyFilter{Key: EventName}, + SequenceDataType: &value, + } + + secondContractFilter := types.ContractKeyFilter{ + Contract: bound, + KeyFilter: query.KeyFilter{Key: DynamicTopicEventName}, + SequenceDataType: &value, + } + + sequencesIter, err := cr.QueryKeys(ctx, []types.ContractKeyFilter{contractFilter, secondContractFilter}, query.LimitAndSort{}) + if err != nil { + return false + } + + sequences := make([]sequenceWithKey, 0) + for k, s := range sequencesIter { + sequences = append(sequences, sequenceWithKey{Sequence: s, Key: k}) + } + + if len(expectedSequenceData) != len(sequences) { + return false + } + + for i, sequence := range sequences { + switch sequence.Key { + case EventName: + val := *sequences[i].Data.(*values.Value) + ts := TestStruct{} + err = val.UnwrapTo(&ts) + require.NoError(t, err) + assert.Equal(t, expectedSequenceData[i], &ts) + case DynamicTopicEventName: + val := *sequences[i].Data.(*values.Value) + ds := SomeDynamicTopicEvent{} + err = val.UnwrapTo(&ds) + require.NoError(t, err) + assert.Equal(t, expectedSequenceData[i], &ds) + default: + return false + } + } + + return true + }, tester.MaxWaitTimeForEvents(), time.Millisecond*10) + }, + }, + + { + Name: ContractReaderQueryKeysCanFilterWithValueComparator, + Test: func(t T) { + ctx := tests.Context(t) + cr := tester.GetContractReader(t) + bindings := tester.GetBindings(t) + + require.NoError(t, cr.Bind(ctx, bindings)) + boundContract := BindingsByName(bindings, AnyContractName)[0] + + expectedSequenceData := createMixedEventTypeSequence(t, tester, boundContract) + + ts := &TestStruct{} + require.Eventually(t, func() bool { + contractFilter := types.ContractKeyFilter{ + Contract: boundContract, + KeyFilter: query.KeyFilter{Key: EventName, + Expressions: []query.Expression{ + query.Comparator("Field", + primitives.ValueComparator{ + Value: 2, + Operator: primitives.Gte, + }, + primitives.ValueComparator{ + Value: 3, + Operator: primitives.Lte, + }), + }}, + SequenceDataType: ts, + } + + ds := SomeDynamicTopicEvent{} + secondContractFilter := types.ContractKeyFilter{ + Contract: boundContract, + KeyFilter: query.KeyFilter{Key: DynamicTopicEventName}, + SequenceDataType: &ds, + } + + sequencesIter, err := cr.QueryKeys(ctx, []types.ContractKeyFilter{contractFilter, secondContractFilter}, query.LimitAndSort{}) + if err != nil { + return false + } + + sequences := make([]sequenceWithKey, 0) + for k, s := range sequencesIter { + sequences = append(sequences, sequenceWithKey{Sequence: s, Key: k}) + } + + expectedSequenceData = expectedSequenceData[2:] + return sequenceDataEqual(expectedSequenceData, sequences) + }, tester.MaxWaitTimeForEvents(), time.Millisecond*500) + }, + }, + { + Name: ContractReaderQueryKeysCanLimitResultsWithCursor, + Test: func(t T) { + ctx := tests.Context(t) + cr := tester.GetContractReader(t) + bindings := tester.GetBindings(t) + + require.NoError(t, cr.Bind(ctx, bindings)) + boundContract := BindingsByName(bindings, AnyContractName)[0] + + var expectedSequenceData []any + + ts1 := CreateTestStruct[T](0, tester) + expectedSequenceData = append(expectedSequenceData, &ts1) + _ = SubmitTransactionToCW(t, tester, MethodTriggeringEvent, ts1, boundContract, types.Unconfirmed) + ts2 := CreateTestStruct[T](1, tester) + expectedSequenceData = append(expectedSequenceData, &ts2) + _ = SubmitTransactionToCW(t, tester, MethodTriggeringEvent, ts2, boundContract, types.Unconfirmed) + + ds1 := SomeDynamicTopicEvent{Field: "1"} + expectedSequenceData = append(expectedSequenceData, &ds1) + _ = SubmitTransactionToCW(t, tester, MethodTriggeringEventWithDynamicTopic, ds1, boundContract, types.Unconfirmed) + + ts3 := CreateTestStruct[T](2, tester) + expectedSequenceData = append(expectedSequenceData, &ts3) + _ = SubmitTransactionToCW(t, tester, MethodTriggeringEvent, ts3, boundContract, types.Unconfirmed) + + ds2 := SomeDynamicTopicEvent{Field: "2"} + expectedSequenceData = append(expectedSequenceData, &ds2) + _ = SubmitTransactionToCW(t, tester, MethodTriggeringEventWithDynamicTopic, ds2, boundContract, types.Unconfirmed) + + ts4 := CreateTestStruct[T](3, tester) + expectedSequenceData = append(expectedSequenceData, &ts4) + _ = SubmitTransactionToCW(t, tester, MethodTriggeringEvent, ts4, boundContract, types.Finalized) + + require.Eventually(t, func() bool { + var allSequences []sequenceWithKey + contractFilter := types.ContractKeyFilter{ + Contract: boundContract, + KeyFilter: query.KeyFilter{Key: EventName, Expressions: []query.Expression{ + query.Confidence(primitives.Finalized), + }}, + SequenceDataType: &TestStruct{}, + } + ds := SomeDynamicTopicEvent{} + secondContractFilter := types.ContractKeyFilter{ + Contract: boundContract, + KeyFilter: query.KeyFilter{Key: DynamicTopicEventName, Expressions: []query.Expression{ + query.Confidence(primitives.Finalized), + }}, + SequenceDataType: &ds, + } + + limit := query.LimitAndSort{ + SortBy: []query.SortBy{query.NewSortBySequence(query.Asc)}, + Limit: query.CountLimit(3), + } + + for idx := 0; idx < len(expectedSequenceData)/2; idx++ { + // sequences from queryKey without limit and sort should be in descending order + sequencesIter, err := cr.QueryKeys(ctx, []types.ContractKeyFilter{secondContractFilter, contractFilter}, limit) + require.NoError(t, err) + + sequences := make([]sequenceWithKey, 0) + for k, s := range sequencesIter { + sequences = append(sequences, sequenceWithKey{Sequence: s, Key: k}) + } + + if len(sequences) == 0 { + continue + } + + limit.Limit = query.CursorLimit(sequences[len(sequences)-1].Cursor, query.CursorFollowing, 3) + allSequences = append(allSequences, sequences...) + } + + return sequenceDataEqual(expectedSequenceData, allSequences) + }, tester.MaxWaitTimeForEvents(), 500*time.Millisecond) + }, + }, + } + + RunTests(t, tester, tests) +} + +func createMixedEventTypeSequence[T TestingT[T]](t T, tester ChainComponentsInterfaceTester[T], boundContract types.BoundContract) []any { + var expectedSequenceData []any + + ts1 := CreateTestStruct[T](0, tester) + expectedSequenceData = append(expectedSequenceData, &ts1) + _ = SubmitTransactionToCW(t, tester, MethodTriggeringEvent, ts1, boundContract, types.Unconfirmed) + ts2 := CreateTestStruct[T](1, tester) + expectedSequenceData = append(expectedSequenceData, &ts2) + _ = SubmitTransactionToCW(t, tester, MethodTriggeringEvent, ts2, boundContract, types.Unconfirmed) + + ds1 := SomeDynamicTopicEvent{Field: "1"} + expectedSequenceData = append(expectedSequenceData, &ds1) + _ = SubmitTransactionToCW(t, tester, MethodTriggeringEventWithDynamicTopic, ds1, boundContract, types.Unconfirmed) + + ts3 := CreateTestStruct[T](2, tester) + expectedSequenceData = append(expectedSequenceData, &ts3) + _ = SubmitTransactionToCW(t, tester, MethodTriggeringEvent, ts3, boundContract, types.Unconfirmed) + + ds2 := SomeDynamicTopicEvent{Field: "2"} + expectedSequenceData = append(expectedSequenceData, &ds2) + _ = SubmitTransactionToCW(t, tester, MethodTriggeringEventWithDynamicTopic, ds2, boundContract, types.Unconfirmed) + + ts4 := CreateTestStruct[T](3, tester) + expectedSequenceData = append(expectedSequenceData, &ts4) + _ = SubmitTransactionToCW(t, tester, MethodTriggeringEvent, ts4, boundContract, types.Unconfirmed) + + return expectedSequenceData +} + +func sequenceDataEqual(expectedSequenceData []any, sequences []sequenceWithKey) bool { + if len(expectedSequenceData) != len(sequences) { + return false + } + + for i, sequence := range sequences { + if !reflect.DeepEqual(sequence.Data, expectedSequenceData[i]) { + return false + } + } + + return true +} + +func runContractReaderGetLatestValueInterfaceTests[T TestingT[T]](t T, tester ChainComponentsInterfaceTester[T], mockRun bool) { tests := []Testcase[T]{ { Name: ContractReaderGetLatestValueAsValuesDotValue, @@ -446,7 +783,6 @@ func runContractReaderGetLatestValueInterfaceTests[T TestingT[T]](t T, tester Ch } func runContractReaderBatchGetLatestValuesInterfaceTests[T TestingT[T]](t T, tester ChainComponentsInterfaceTester[T], mockRun bool) { - testCases := []Testcase[T]{ { Name: ContractReaderBatchGetLatestValue, diff --git a/pkg/types/interfacetests/utils.go b/pkg/types/interfacetests/utils.go index 203ff1980..5f81cd206 100644 --- a/pkg/types/interfacetests/utils.go +++ b/pkg/types/interfacetests/utils.go @@ -8,9 +8,10 @@ import ( "time" "github.com/google/uuid" - "github.com/smartcontractkit/libocr/commontypes" "github.com/stretchr/testify/require" + "github.com/smartcontractkit/libocr/commontypes" + "github.com/smartcontractkit/chainlink-common/pkg/types" "github.com/smartcontractkit/chainlink-common/pkg/types/query/primitives" "github.com/smartcontractkit/chainlink-common/pkg/utils/tests" diff --git a/pkg/values/value.go b/pkg/values/value.go index 540040a4c..ac109fd9c 100644 --- a/pkg/values/value.go +++ b/pkg/values/value.go @@ -318,7 +318,7 @@ func CreateMapFromStruct(v any) (*Map, error) { if !field.IsExported() { continue } - // for backwards compatability, use tagged mapstructure tag as key if provided + // for backwards compatibility, use tagged mapstructure tag as key if provided msTag := field.Tag.Get("mapstructure") key := msTag if key == "" {