From 5f66edafb1dad726837f700057dbba9662e2e2c3 Mon Sep 17 00:00:00 2001 From: Aaron Sutula Date: Wed, 24 Feb 2021 18:06:44 -0600 Subject: [PATCH 01/16] first work on sendfil service Signed-off-by: Aaron Sutula --- api/sendfild/pb/sendfil.pb.go | 739 +++++++++++++++++++++++++++ api/sendfild/pb/sendfil.proto | 50 ++ api/sendfild/service/service.go | 415 +++++++++++++++ api/sendfild/service/service_test.go | 102 ++++ go.mod | 2 + go.sum | 4 + 6 files changed, 1312 insertions(+) create mode 100644 api/sendfild/pb/sendfil.pb.go create mode 100644 api/sendfild/pb/sendfil.proto create mode 100644 api/sendfild/service/service.go create mode 100644 api/sendfild/service/service_test.go diff --git a/api/sendfild/pb/sendfil.pb.go b/api/sendfild/pb/sendfil.pb.go new file mode 100644 index 000000000..63e22acf0 --- /dev/null +++ b/api/sendfild/pb/sendfil.pb.go @@ -0,0 +1,739 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.23.0 +// protoc v3.13.0 +// source: api/sendfild/pb/sendfil.proto + +package pb + +import ( + context "context" + proto "github.com/golang/protobuf/proto" + timestamp "github.com/golang/protobuf/ptypes/timestamp" + grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +// This is a compile-time assertion that a sufficiently up-to-date version +// of the legacy proto package is being used. +const _ = proto.ProtoPackageIsVersion4 + +type MessageState int32 + +const ( + MessageState_MESSAGE_STATE_UNSPECIFIED MessageState = 0 + MessageState_MESSAGE_STATE_PENDING MessageState = 1 + MessageState_MESSAGE_STATE_ACTIVE MessageState = 2 + MessageState_MESSAGE_STATE_FAILED MessageState = 3 +) + +// Enum value maps for MessageState. +var ( + MessageState_name = map[int32]string{ + 0: "MESSAGE_STATE_UNSPECIFIED", + 1: "MESSAGE_STATE_PENDING", + 2: "MESSAGE_STATE_ACTIVE", + 3: "MESSAGE_STATE_FAILED", + } + MessageState_value = map[string]int32{ + "MESSAGE_STATE_UNSPECIFIED": 0, + "MESSAGE_STATE_PENDING": 1, + "MESSAGE_STATE_ACTIVE": 2, + "MESSAGE_STATE_FAILED": 3, + } +) + +func (x MessageState) Enum() *MessageState { + p := new(MessageState) + *p = x + return p +} + +func (x MessageState) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (MessageState) Descriptor() protoreflect.EnumDescriptor { + return file_api_sendfild_pb_sendfil_proto_enumTypes[0].Descriptor() +} + +func (MessageState) Type() protoreflect.EnumType { + return &file_api_sendfild_pb_sendfil_proto_enumTypes[0] +} + +func (x MessageState) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use MessageState.Descriptor instead. +func (MessageState) EnumDescriptor() ([]byte, []int) { + return file_api_sendfild_pb_sendfil_proto_rawDescGZIP(), []int{0} +} + +type Txn struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + From string `protobuf:"bytes,2,opt,name=from,proto3" json:"from,omitempty"` + To string `protobuf:"bytes,3,opt,name=to,proto3" json:"to,omitempty"` + Amount string `protobuf:"bytes,4,opt,name=amount,proto3" json:"amount,omitempty"` + MessageCid string `protobuf:"bytes,5,opt,name=message_cid,json=messageCid,proto3" json:"message_cid,omitempty"` + MessageState MessageState `protobuf:"varint,6,opt,name=message_state,json=messageState,proto3,enum=api.sendfild.pb.MessageState" json:"message_state,omitempty"` + Waiting bool `protobuf:"varint,7,opt,name=waiting,proto3" json:"waiting,omitempty"` + FailureMsg string `protobuf:"bytes,8,opt,name=failure_msg,json=failureMsg,proto3" json:"failure_msg,omitempty"` + CreatedAt *timestamp.Timestamp `protobuf:"bytes,9,opt,name=created_at,json=createdAt,proto3" json:"created_at,omitempty"` + UpdatedAt *timestamp.Timestamp `protobuf:"bytes,10,opt,name=updated_at,json=updatedAt,proto3" json:"updated_at,omitempty"` +} + +func (x *Txn) Reset() { + *x = Txn{} + if protoimpl.UnsafeEnabled { + mi := &file_api_sendfild_pb_sendfil_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Txn) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Txn) ProtoMessage() {} + +func (x *Txn) ProtoReflect() protoreflect.Message { + mi := &file_api_sendfild_pb_sendfil_proto_msgTypes[0] + 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 Txn.ProtoReflect.Descriptor instead. +func (*Txn) Descriptor() ([]byte, []int) { + return file_api_sendfild_pb_sendfil_proto_rawDescGZIP(), []int{0} +} + +func (x *Txn) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +func (x *Txn) GetFrom() string { + if x != nil { + return x.From + } + return "" +} + +func (x *Txn) GetTo() string { + if x != nil { + return x.To + } + return "" +} + +func (x *Txn) GetAmount() string { + if x != nil { + return x.Amount + } + return "" +} + +func (x *Txn) GetMessageCid() string { + if x != nil { + return x.MessageCid + } + return "" +} + +func (x *Txn) GetMessageState() MessageState { + if x != nil { + return x.MessageState + } + return MessageState_MESSAGE_STATE_UNSPECIFIED +} + +func (x *Txn) GetWaiting() bool { + if x != nil { + return x.Waiting + } + return false +} + +func (x *Txn) GetFailureMsg() string { + if x != nil { + return x.FailureMsg + } + return "" +} + +func (x *Txn) GetCreatedAt() *timestamp.Timestamp { + if x != nil { + return x.CreatedAt + } + return nil +} + +func (x *Txn) GetUpdatedAt() *timestamp.Timestamp { + if x != nil { + return x.UpdatedAt + } + return nil +} + +type SendFilRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + From string `protobuf:"bytes,1,opt,name=from,proto3" json:"from,omitempty"` + To string `protobuf:"bytes,2,opt,name=to,proto3" json:"to,omitempty"` + Amount string `protobuf:"bytes,3,opt,name=amount,proto3" json:"amount,omitempty"` + Wait bool `protobuf:"varint,4,opt,name=wait,proto3" json:"wait,omitempty"` +} + +func (x *SendFilRequest) Reset() { + *x = SendFilRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_api_sendfild_pb_sendfil_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *SendFilRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SendFilRequest) ProtoMessage() {} + +func (x *SendFilRequest) ProtoReflect() protoreflect.Message { + mi := &file_api_sendfild_pb_sendfil_proto_msgTypes[1] + 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 SendFilRequest.ProtoReflect.Descriptor instead. +func (*SendFilRequest) Descriptor() ([]byte, []int) { + return file_api_sendfild_pb_sendfil_proto_rawDescGZIP(), []int{1} +} + +func (x *SendFilRequest) GetFrom() string { + if x != nil { + return x.From + } + return "" +} + +func (x *SendFilRequest) GetTo() string { + if x != nil { + return x.To + } + return "" +} + +func (x *SendFilRequest) GetAmount() string { + if x != nil { + return x.Amount + } + return "" +} + +func (x *SendFilRequest) GetWait() bool { + if x != nil { + return x.Wait + } + return false +} + +type SendFilResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Txn *Txn `protobuf:"bytes,1,opt,name=txn,proto3" json:"txn,omitempty"` +} + +func (x *SendFilResponse) Reset() { + *x = SendFilResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_api_sendfild_pb_sendfil_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *SendFilResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SendFilResponse) ProtoMessage() {} + +func (x *SendFilResponse) ProtoReflect() protoreflect.Message { + mi := &file_api_sendfild_pb_sendfil_proto_msgTypes[2] + 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 SendFilResponse.ProtoReflect.Descriptor instead. +func (*SendFilResponse) Descriptor() ([]byte, []int) { + return file_api_sendfild_pb_sendfil_proto_rawDescGZIP(), []int{2} +} + +func (x *SendFilResponse) GetTxn() *Txn { + if x != nil { + return x.Txn + } + return nil +} + +type TxnRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + MessageCid string `protobuf:"bytes,1,opt,name=message_cid,json=messageCid,proto3" json:"message_cid,omitempty"` + Wait bool `protobuf:"varint,2,opt,name=wait,proto3" json:"wait,omitempty"` +} + +func (x *TxnRequest) Reset() { + *x = TxnRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_api_sendfild_pb_sendfil_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *TxnRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*TxnRequest) ProtoMessage() {} + +func (x *TxnRequest) ProtoReflect() protoreflect.Message { + mi := &file_api_sendfild_pb_sendfil_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 TxnRequest.ProtoReflect.Descriptor instead. +func (*TxnRequest) Descriptor() ([]byte, []int) { + return file_api_sendfild_pb_sendfil_proto_rawDescGZIP(), []int{3} +} + +func (x *TxnRequest) GetMessageCid() string { + if x != nil { + return x.MessageCid + } + return "" +} + +func (x *TxnRequest) GetWait() bool { + if x != nil { + return x.Wait + } + return false +} + +type TxnResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Txn *Txn `protobuf:"bytes,1,opt,name=txn,proto3" json:"txn,omitempty"` +} + +func (x *TxnResponse) Reset() { + *x = TxnResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_api_sendfild_pb_sendfil_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *TxnResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*TxnResponse) ProtoMessage() {} + +func (x *TxnResponse) ProtoReflect() protoreflect.Message { + mi := &file_api_sendfild_pb_sendfil_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 TxnResponse.ProtoReflect.Descriptor instead. +func (*TxnResponse) Descriptor() ([]byte, []int) { + return file_api_sendfild_pb_sendfil_proto_rawDescGZIP(), []int{4} +} + +func (x *TxnResponse) GetTxn() *Txn { + if x != nil { + return x.Txn + } + return nil +} + +var File_api_sendfild_pb_sendfil_proto protoreflect.FileDescriptor + +var file_api_sendfild_pb_sendfil_proto_rawDesc = []byte{ + 0x0a, 0x1d, 0x61, 0x70, 0x69, 0x2f, 0x73, 0x65, 0x6e, 0x64, 0x66, 0x69, 0x6c, 0x64, 0x2f, 0x70, + 0x62, 0x2f, 0x73, 0x65, 0x6e, 0x64, 0x66, 0x69, 0x6c, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, + 0x0f, 0x61, 0x70, 0x69, 0x2e, 0x73, 0x65, 0x6e, 0x64, 0x66, 0x69, 0x6c, 0x64, 0x2e, 0x70, 0x62, + 0x1a, 0x1f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, + 0x66, 0x2f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x22, 0xe7, 0x02, 0x0a, 0x03, 0x54, 0x78, 0x6e, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x66, 0x72, 0x6f, + 0x6d, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x66, 0x72, 0x6f, 0x6d, 0x12, 0x0e, 0x0a, + 0x02, 0x74, 0x6f, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x74, 0x6f, 0x12, 0x16, 0x0a, + 0x06, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x61, + 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x1f, 0x0a, 0x0b, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, + 0x5f, 0x63, 0x69, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x6d, 0x65, 0x73, 0x73, + 0x61, 0x67, 0x65, 0x43, 0x69, 0x64, 0x12, 0x42, 0x0a, 0x0d, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, + 0x65, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1d, 0x2e, + 0x61, 0x70, 0x69, 0x2e, 0x73, 0x65, 0x6e, 0x64, 0x66, 0x69, 0x6c, 0x64, 0x2e, 0x70, 0x62, 0x2e, + 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x0c, 0x6d, 0x65, + 0x73, 0x73, 0x61, 0x67, 0x65, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x77, 0x61, + 0x69, 0x74, 0x69, 0x6e, 0x67, 0x18, 0x07, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x77, 0x61, 0x69, + 0x74, 0x69, 0x6e, 0x67, 0x12, 0x1f, 0x0a, 0x0b, 0x66, 0x61, 0x69, 0x6c, 0x75, 0x72, 0x65, 0x5f, + 0x6d, 0x73, 0x67, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x66, 0x61, 0x69, 0x6c, 0x75, + 0x72, 0x65, 0x4d, 0x73, 0x67, 0x12, 0x39, 0x0a, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, + 0x5f, 0x61, 0x74, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, + 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, + 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, + 0x12, 0x39, 0x0a, 0x0a, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x0a, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, + 0x52, 0x09, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x22, 0x60, 0x0a, 0x0e, 0x53, + 0x65, 0x6e, 0x64, 0x46, 0x69, 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, + 0x04, 0x66, 0x72, 0x6f, 0x6d, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x66, 0x72, 0x6f, + 0x6d, 0x12, 0x0e, 0x0a, 0x02, 0x74, 0x6f, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x74, + 0x6f, 0x12, 0x16, 0x0a, 0x06, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x06, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x77, 0x61, 0x69, + 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x04, 0x77, 0x61, 0x69, 0x74, 0x22, 0x39, 0x0a, + 0x0f, 0x53, 0x65, 0x6e, 0x64, 0x46, 0x69, 0x6c, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x12, 0x26, 0x0a, 0x03, 0x74, 0x78, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, + 0x61, 0x70, 0x69, 0x2e, 0x73, 0x65, 0x6e, 0x64, 0x66, 0x69, 0x6c, 0x64, 0x2e, 0x70, 0x62, 0x2e, + 0x54, 0x78, 0x6e, 0x52, 0x03, 0x74, 0x78, 0x6e, 0x22, 0x41, 0x0a, 0x0a, 0x54, 0x78, 0x6e, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1f, 0x0a, 0x0b, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, + 0x65, 0x5f, 0x63, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x6d, 0x65, 0x73, + 0x73, 0x61, 0x67, 0x65, 0x43, 0x69, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x77, 0x61, 0x69, 0x74, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x04, 0x77, 0x61, 0x69, 0x74, 0x22, 0x35, 0x0a, 0x0b, 0x54, + 0x78, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x26, 0x0a, 0x03, 0x74, 0x78, + 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x73, 0x65, + 0x6e, 0x64, 0x66, 0x69, 0x6c, 0x64, 0x2e, 0x70, 0x62, 0x2e, 0x54, 0x78, 0x6e, 0x52, 0x03, 0x74, + 0x78, 0x6e, 0x2a, 0x7c, 0x0a, 0x0c, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x53, 0x74, 0x61, + 0x74, 0x65, 0x12, 0x1d, 0x0a, 0x19, 0x4d, 0x45, 0x53, 0x53, 0x41, 0x47, 0x45, 0x5f, 0x53, 0x54, + 0x41, 0x54, 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, + 0x00, 0x12, 0x19, 0x0a, 0x15, 0x4d, 0x45, 0x53, 0x53, 0x41, 0x47, 0x45, 0x5f, 0x53, 0x54, 0x41, + 0x54, 0x45, 0x5f, 0x50, 0x45, 0x4e, 0x44, 0x49, 0x4e, 0x47, 0x10, 0x01, 0x12, 0x18, 0x0a, 0x14, + 0x4d, 0x45, 0x53, 0x53, 0x41, 0x47, 0x45, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x45, 0x5f, 0x41, 0x43, + 0x54, 0x49, 0x56, 0x45, 0x10, 0x02, 0x12, 0x18, 0x0a, 0x14, 0x4d, 0x45, 0x53, 0x53, 0x41, 0x47, + 0x45, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x45, 0x5f, 0x46, 0x41, 0x49, 0x4c, 0x45, 0x44, 0x10, 0x03, + 0x32, 0xa4, 0x01, 0x0a, 0x0e, 0x53, 0x65, 0x6e, 0x64, 0x46, 0x69, 0x6c, 0x53, 0x65, 0x72, 0x76, + 0x69, 0x63, 0x65, 0x12, 0x4e, 0x0a, 0x07, 0x53, 0x65, 0x6e, 0x64, 0x46, 0x69, 0x6c, 0x12, 0x1f, + 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x73, 0x65, 0x6e, 0x64, 0x66, 0x69, 0x6c, 0x64, 0x2e, 0x70, 0x62, + 0x2e, 0x53, 0x65, 0x6e, 0x64, 0x46, 0x69, 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x20, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x73, 0x65, 0x6e, 0x64, 0x66, 0x69, 0x6c, 0x64, 0x2e, 0x70, + 0x62, 0x2e, 0x53, 0x65, 0x6e, 0x64, 0x46, 0x69, 0x6c, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x22, 0x00, 0x12, 0x42, 0x0a, 0x03, 0x54, 0x78, 0x6e, 0x12, 0x1b, 0x2e, 0x61, 0x70, 0x69, + 0x2e, 0x73, 0x65, 0x6e, 0x64, 0x66, 0x69, 0x6c, 0x64, 0x2e, 0x70, 0x62, 0x2e, 0x54, 0x78, 0x6e, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1c, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x73, 0x65, + 0x6e, 0x64, 0x66, 0x69, 0x6c, 0x64, 0x2e, 0x70, 0x62, 0x2e, 0x54, 0x78, 0x6e, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x42, 0x31, 0x5a, 0x2f, 0x67, 0x69, 0x74, 0x68, 0x75, + 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x74, 0x65, 0x78, 0x74, 0x69, 0x6c, 0x65, 0x69, 0x6f, 0x2f, + 0x74, 0x65, 0x78, 0x74, 0x69, 0x6c, 0x65, 0x2f, 0x76, 0x32, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x73, + 0x65, 0x6e, 0x64, 0x66, 0x69, 0x6c, 0x64, 0x2f, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x33, +} + +var ( + file_api_sendfild_pb_sendfil_proto_rawDescOnce sync.Once + file_api_sendfild_pb_sendfil_proto_rawDescData = file_api_sendfild_pb_sendfil_proto_rawDesc +) + +func file_api_sendfild_pb_sendfil_proto_rawDescGZIP() []byte { + file_api_sendfild_pb_sendfil_proto_rawDescOnce.Do(func() { + file_api_sendfild_pb_sendfil_proto_rawDescData = protoimpl.X.CompressGZIP(file_api_sendfild_pb_sendfil_proto_rawDescData) + }) + return file_api_sendfild_pb_sendfil_proto_rawDescData +} + +var file_api_sendfild_pb_sendfil_proto_enumTypes = make([]protoimpl.EnumInfo, 1) +var file_api_sendfild_pb_sendfil_proto_msgTypes = make([]protoimpl.MessageInfo, 5) +var file_api_sendfild_pb_sendfil_proto_goTypes = []interface{}{ + (MessageState)(0), // 0: api.sendfild.pb.MessageState + (*Txn)(nil), // 1: api.sendfild.pb.Txn + (*SendFilRequest)(nil), // 2: api.sendfild.pb.SendFilRequest + (*SendFilResponse)(nil), // 3: api.sendfild.pb.SendFilResponse + (*TxnRequest)(nil), // 4: api.sendfild.pb.TxnRequest + (*TxnResponse)(nil), // 5: api.sendfild.pb.TxnResponse + (*timestamp.Timestamp)(nil), // 6: google.protobuf.Timestamp +} +var file_api_sendfild_pb_sendfil_proto_depIdxs = []int32{ + 0, // 0: api.sendfild.pb.Txn.message_state:type_name -> api.sendfild.pb.MessageState + 6, // 1: api.sendfild.pb.Txn.created_at:type_name -> google.protobuf.Timestamp + 6, // 2: api.sendfild.pb.Txn.updated_at:type_name -> google.protobuf.Timestamp + 1, // 3: api.sendfild.pb.SendFilResponse.txn:type_name -> api.sendfild.pb.Txn + 1, // 4: api.sendfild.pb.TxnResponse.txn:type_name -> api.sendfild.pb.Txn + 2, // 5: api.sendfild.pb.SendFilService.SendFil:input_type -> api.sendfild.pb.SendFilRequest + 4, // 6: api.sendfild.pb.SendFilService.Txn:input_type -> api.sendfild.pb.TxnRequest + 3, // 7: api.sendfild.pb.SendFilService.SendFil:output_type -> api.sendfild.pb.SendFilResponse + 5, // 8: api.sendfild.pb.SendFilService.Txn:output_type -> api.sendfild.pb.TxnResponse + 7, // [7:9] is the sub-list for method output_type + 5, // [5:7] is the sub-list for method input_type + 5, // [5:5] is the sub-list for extension type_name + 5, // [5:5] is the sub-list for extension extendee + 0, // [0:5] is the sub-list for field type_name +} + +func init() { file_api_sendfild_pb_sendfil_proto_init() } +func file_api_sendfild_pb_sendfil_proto_init() { + if File_api_sendfild_pb_sendfil_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_api_sendfild_pb_sendfil_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Txn); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_api_sendfild_pb_sendfil_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*SendFilRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_api_sendfild_pb_sendfil_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*SendFilResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_api_sendfild_pb_sendfil_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*TxnRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_api_sendfild_pb_sendfil_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*TxnResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_api_sendfild_pb_sendfil_proto_rawDesc, + NumEnums: 1, + NumMessages: 5, + NumExtensions: 0, + NumServices: 1, + }, + GoTypes: file_api_sendfild_pb_sendfil_proto_goTypes, + DependencyIndexes: file_api_sendfild_pb_sendfil_proto_depIdxs, + EnumInfos: file_api_sendfild_pb_sendfil_proto_enumTypes, + MessageInfos: file_api_sendfild_pb_sendfil_proto_msgTypes, + }.Build() + File_api_sendfild_pb_sendfil_proto = out.File + file_api_sendfild_pb_sendfil_proto_rawDesc = nil + file_api_sendfild_pb_sendfil_proto_goTypes = nil + file_api_sendfild_pb_sendfil_proto_depIdxs = nil +} + +// Reference imports to suppress errors if they are not otherwise used. +var _ context.Context +var _ grpc.ClientConnInterface + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +const _ = grpc.SupportPackageIsVersion6 + +// SendFilServiceClient is the client API for SendFilService service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. +type SendFilServiceClient interface { + SendFil(ctx context.Context, in *SendFilRequest, opts ...grpc.CallOption) (*SendFilResponse, error) + Txn(ctx context.Context, in *TxnRequest, opts ...grpc.CallOption) (*TxnResponse, error) +} + +type sendFilServiceClient struct { + cc grpc.ClientConnInterface +} + +func NewSendFilServiceClient(cc grpc.ClientConnInterface) SendFilServiceClient { + return &sendFilServiceClient{cc} +} + +func (c *sendFilServiceClient) SendFil(ctx context.Context, in *SendFilRequest, opts ...grpc.CallOption) (*SendFilResponse, error) { + out := new(SendFilResponse) + err := c.cc.Invoke(ctx, "/api.sendfild.pb.SendFilService/SendFil", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *sendFilServiceClient) Txn(ctx context.Context, in *TxnRequest, opts ...grpc.CallOption) (*TxnResponse, error) { + out := new(TxnResponse) + err := c.cc.Invoke(ctx, "/api.sendfild.pb.SendFilService/Txn", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// SendFilServiceServer is the server API for SendFilService service. +type SendFilServiceServer interface { + SendFil(context.Context, *SendFilRequest) (*SendFilResponse, error) + Txn(context.Context, *TxnRequest) (*TxnResponse, error) +} + +// UnimplementedSendFilServiceServer can be embedded to have forward compatible implementations. +type UnimplementedSendFilServiceServer struct { +} + +func (*UnimplementedSendFilServiceServer) SendFil(context.Context, *SendFilRequest) (*SendFilResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method SendFil not implemented") +} +func (*UnimplementedSendFilServiceServer) Txn(context.Context, *TxnRequest) (*TxnResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method Txn not implemented") +} + +func RegisterSendFilServiceServer(s *grpc.Server, srv SendFilServiceServer) { + s.RegisterService(&_SendFilService_serviceDesc, srv) +} + +func _SendFilService_SendFil_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(SendFilRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(SendFilServiceServer).SendFil(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/api.sendfild.pb.SendFilService/SendFil", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(SendFilServiceServer).SendFil(ctx, req.(*SendFilRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _SendFilService_Txn_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(TxnRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(SendFilServiceServer).Txn(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/api.sendfild.pb.SendFilService/Txn", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(SendFilServiceServer).Txn(ctx, req.(*TxnRequest)) + } + return interceptor(ctx, in, info, handler) +} + +var _SendFilService_serviceDesc = grpc.ServiceDesc{ + ServiceName: "api.sendfild.pb.SendFilService", + HandlerType: (*SendFilServiceServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "SendFil", + Handler: _SendFilService_SendFil_Handler, + }, + { + MethodName: "Txn", + Handler: _SendFilService_Txn_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "api/sendfild/pb/sendfil.proto", +} diff --git a/api/sendfild/pb/sendfil.proto b/api/sendfild/pb/sendfil.proto new file mode 100644 index 000000000..eb708807f --- /dev/null +++ b/api/sendfild/pb/sendfil.proto @@ -0,0 +1,50 @@ +syntax = "proto3"; +package api.sendfild.pb; +option go_package = "github.com/textileio/textile/v2/api/sendfild/pb"; + +import "google/protobuf/timestamp.proto"; + +enum MessageState { + MESSAGE_STATE_UNSPECIFIED = 0; + MESSAGE_STATE_PENDING = 1; + MESSAGE_STATE_ACTIVE = 2; + MESSAGE_STATE_FAILED = 3; +} + +message Txn { + string id = 1; + string from = 2; + string to = 3; + string amount = 4; + string message_cid = 5; + MessageState message_state = 6; + bool waiting = 7; + string failure_msg = 8; + google.protobuf.Timestamp created_at = 9; + google.protobuf.Timestamp updated_at = 10; +} + +message SendFilRequest { + string from = 1; + string to = 2; + string amount = 3; + bool wait = 4; +} + +message SendFilResponse { + Txn txn = 1; +} + +message TxnRequest { + string message_cid = 1; + bool wait = 2; +} + +message TxnResponse { + Txn txn = 1; +} + +service SendFilService { + rpc SendFil(SendFilRequest) returns (SendFilResponse) {} + rpc Txn(TxnRequest) returns (TxnResponse) {} +} \ No newline at end of file diff --git a/api/sendfild/service/service.go b/api/sendfild/service/service.go new file mode 100644 index 000000000..66fc44200 --- /dev/null +++ b/api/sendfild/service/service.go @@ -0,0 +1,415 @@ +package service + +import ( + "context" + "errors" + "fmt" + "math/big" + "net" + "sync" + "time" + + "github.com/filecoin-project/go-address" + "github.com/filecoin-project/lotus/chain/types" + "github.com/ipfs/go-cid" + logging "github.com/ipfs/go-log/v2" + "github.com/textileio/go-threads/util" + "github.com/textileio/powergate/v2/lotus" + pb "github.com/textileio/textile/v2/api/sendfild/pb" + "go.mongodb.org/mongo-driver/bson" + "go.mongodb.org/mongo-driver/bson/primitive" + "go.mongodb.org/mongo-driver/mongo" + "go.mongodb.org/mongo-driver/mongo/options" + "google.golang.org/grpc" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" + "google.golang.org/protobuf/types/known/timestamppb" +) + +const ( + collectionName = "sendfil" +) + +var _ pb.SendFilServiceServer = (*Service)(nil) + +var log = logging.Logger("sendfil") + +type msgCid struct { + Cid string `bson:"cid"` + CreatedAt time.Time `bson:"created_at"` +} + +type txn struct { + ID primitive.ObjectID `bson:"_id"` + From string `bson:"from"` + To string `bson:"to"` + Amount string `bson:"amount"` + MessageCids []msgCid `bson:"message_cids"` + MessageState pb.MessageState `bson:"message_state"` + Waiting bool `bson:"waiting"` + FailureMsg string `bson:"failure_msg"` + CreatedAt time.Time `bson:"created_at"` + UpdatedAt time.Time `bson:"updated_at"` +} + +func (t txn) latestMsgCid() (msgCid, error) { + if len(t.MessageCids) == 0 { + return msgCid{}, fmt.Errorf("no message cids found") + } + return t.MessageCids[len(t.MessageCids)-1], nil +} + +type Service struct { + clientBuilder lotus.ClientBuilder + col *mongo.Collection + server *grpc.Server + waiting map[primitive.ObjectID]chan waitResult + waitingLck sync.Mutex +} + +type Config struct { + Listener net.Listener + ClientBuilder lotus.ClientBuilder + MongoUri string + MongoDbName string + Debug bool +} + +func New(ctx context.Context, config Config) (*Service, error) { + if config.Debug { + if err := util.SetLogLevels(map[string]logging.LogLevel{ + "sendfil": logging.LevelDebug, + }); err != nil { + return nil, err + } + } + + client, err := mongo.Connect(ctx, options.Client().ApplyURI(config.MongoUri)) + if err != nil { + return nil, fmt.Errorf("connecting to mongo: %v", err) + } + db := client.Database(config.MongoDbName) + col := db.Collection(collectionName) + if _, err := col.Indexes().CreateMany(ctx, []mongo.IndexModel{ + { + Keys: bson.D{primitive.E{Key: "from", Value: 1}}, + }, + { + Keys: bson.D{primitive.E{Key: "to", Value: 1}}, + }, + { + Keys: bson.D{primitive.E{Key: "amount", Value: 1}}, + }, + // MongoDB automatically creates a multikey index if any indexed field is an array; + // you do not need to explicitly specify the multikey type. + // https://docs.mongodb.com/manual/core/index-multikey/ + { + Keys: bson.D{primitive.E{Key: "message_cids.cid", Value: 1}}, + Options: options.Index().SetUnique(true), + }, + { + Keys: bson.D{primitive.E{Key: "message_state", Value: 1}}, + }, + { + Keys: bson.D{primitive.E{Key: "waiting", Value: 1}}, + }, + { + Keys: bson.D{primitive.E{Key: "created_at", Value: 1}}, + }, + { + Keys: bson.D{primitive.E{Key: "updated_at", Value: 1}}, + }, + }); err != nil { + return nil, fmt.Errorf("creating collection indexes: %v", err) + } + + s := &Service{ + clientBuilder: config.ClientBuilder, + col: col, + waiting: make(map[primitive.ObjectID]chan waitResult), + } + + s.server = grpc.NewServer() + go func() { + pb.RegisterSendFilServiceServer(s.server, s) + if err := s.server.Serve(config.Listener); err != nil && !errors.Is(err, grpc.ErrServerStopped) { + log.Errorf("serve error: %v", err) + } + }() + + return s, nil +} + +func (s *Service) SendFil(ctx context.Context, req *pb.SendFilRequest) (*pb.SendFilResponse, error) { + f, err := address.NewFromString(req.From) + if err != nil { + return nil, status.Errorf(codes.InvalidArgument, "parsing from address: %v", err) + } + t, err := address.NewFromString(req.To) + if err != nil { + return nil, status.Errorf(codes.InvalidArgument, "parsing to address: %v", err) + } + amount := &big.Int{} + _, ok := amount.SetString(req.Amount, 10) + if !ok { + return nil, status.Error(codes.InvalidArgument, "parsing amount") + } + msg := &types.Message{ + From: f, + To: t, + Value: types.BigInt{Int: amount}, + } + client, cls, err := s.clientBuilder(ctx) + if err != nil { + return nil, status.Errorf(codes.Internal, "creating filecoin client: %v", err) + } + defer cls() + + sm, err := client.MpoolPushMessage(ctx, msg, nil) + if err != nil { + return nil, status.Errorf(codes.Internal, "pushing message: %v", err) + } + + now := time.Now() + + tx := txn{ + ID: primitive.NewObjectID(), + From: req.From, + To: req.To, + Amount: req.Amount, + MessageCids: []msgCid{{Cid: sm.Message.Cid().String(), CreatedAt: now}}, + MessageState: pb.MessageState_MESSAGE_STATE_PENDING, + CreatedAt: now, + UpdatedAt: now, + } + + if _, err = s.col.InsertOne(ctx, &tx); err != nil { + return nil, status.Errorf(codes.Internal, "inserting txn into collection: %v", err) + } + + wait := s.wait(tx) + + if req.Wait { + res := <-wait + if res.err != nil { + return nil, status.Errorf(codes.Internal, "waiting for result: %v", res.err) + } + tx = res.txn + } + + pbTx, err := toPbTxn(tx) + if err != nil { + return nil, status.Errorf(codes.Internal, "converting to pb txn: %v", err) + } + + return &pb.SendFilResponse{Txn: pbTx}, nil +} + +func (s *Service) Txn(ctx context.Context, req *pb.TxnRequest) (*pb.TxnResponse, error) { + res := s.col.FindOne(ctx, bson.M{"message_cids.cid": req.MessageCid}) + if res.Err() == mongo.ErrNoDocuments { + return nil, status.Error(codes.InvalidArgument, "no txn found for cid") + } + if res.Err() != nil { + return nil, status.Errorf(codes.Internal, "querying for cid txn: %v", res.Err()) + } + + var tx txn + if err := res.Decode(&tx); err != nil { + return nil, status.Errorf(codes.Internal, "decoding cid txn result: %v", res.Err()) + } + + if tx.MessageState != pb.MessageState_MESSAGE_STATE_ACTIVE && tx.MessageState != pb.MessageState_MESSAGE_STATE_FAILED && req.Wait { + res := <-s.wait(tx) + if res.err != nil { + return nil, status.Errorf(codes.Internal, "waiting for result: %v", res.err) + } + tx = res.txn + } + + pbTx, err := toPbTxn(tx) + if err != nil { + return nil, status.Errorf(codes.Internal, "converting to pb txn: %v", err) + } + + return &pb.TxnResponse{Txn: pbTx}, nil +} + +type waitResult struct { + txn txn + err error +} + +func (s *Service) wait(tx txn) chan waitResult { + s.waitingLck.Lock() + defer s.waitingLck.Unlock() + + waitCh, found := s.waiting[tx.ID] + if found { + return waitCh + } + + ch := make(chan waitResult) + s.waiting[tx.ID] = ch + + go func() { + // ToDo: make timeout configurable + ctx, cancel := context.WithTimeout(context.Background(), time.Minute*5) + + client, closeClient, err := s.clientBuilder(ctx) + defer func() { + closeClient() + close(ch) + cancel() + }() + if err != nil { + ch <- waitResult{err: fmt.Errorf("creating lotus client: %v", err)} + return + } + + lastestMsgCid, err := tx.latestMsgCid() + if err != nil { + tx.MessageState = pb.MessageState_MESSAGE_STATE_FAILED + tx.FailureMsg = fmt.Sprintf("getting latest message cid from txn: %v", err) + tx.UpdatedAt = time.Now() + if err := s.updateTxn(ctx, tx); err != nil { + ch <- waitResult{err: err} + return + } + ch <- waitResult{txn: tx} + return + } + c, err := cid.Decode(lastestMsgCid.Cid) + if err != nil { + tx.MessageState = pb.MessageState_MESSAGE_STATE_FAILED + tx.FailureMsg = fmt.Sprintf("decoding latest message cid for txn: %v", err) + tx.UpdatedAt = time.Now() + if err := s.updateTxn(ctx, tx); err != nil { + ch <- waitResult{err: err} + return + } + ch <- waitResult{txn: tx} + return + } + + tx.Waiting = true + if err := s.updateTxn(ctx, tx); err != nil { + ch <- waitResult{err: err} + return + } + + // ToDo: Make confidence configurable + res, err := client.StateWaitMsg(ctx, c, 3) + tx.Waiting = false + if err != nil { + if err := s.updateTxn(ctx, tx); err != nil { + ch <- waitResult{err: err} + return + } + ch <- waitResult{err: fmt.Errorf("calling StateWaitMsg: %v", err)} + return + } + + if res.Receipt.ExitCode.IsError() { + tx.MessageState = pb.MessageState_MESSAGE_STATE_FAILED + tx.FailureMsg = fmt.Sprintf("error exit code: %v", res.Receipt.ExitCode.Error()) + tx.UpdatedAt = time.Now() + if err := s.updateTxn(ctx, tx); err != nil { + ch <- waitResult{err: err} + return + } + ch <- waitResult{txn: tx} + if res.Receipt.ExitCode.IsSendFailure() { + log.Errorf("received exit code send failure: %s", res.Receipt.ExitCode.String()) + } else { + log.Infof("received exit code error: %s", res.Receipt.ExitCode.String()) + } + return + } + + tx.MessageState = pb.MessageState_MESSAGE_STATE_ACTIVE + tx.UpdatedAt = time.Now() + + // This would probably not ever be true because we would already know about and have tracked + // the new message cid if we replaced the message with a new one. Checking just in case. + isNewCid := true + for _, msgCid := range tx.MessageCids { + if res.Message.String() == msgCid.Cid { + isNewCid = false + break + } + } + + if isNewCid { + tx.MessageCids = append(tx.MessageCids, msgCid{Cid: res.Message.String(), CreatedAt: time.Now()}) + } + + if err := s.updateTxn(ctx, tx); err != nil { + ch <- waitResult{err: err} + return + } + + s.waitingLck.Lock() + delete(s.waiting, tx.ID) + s.waitingLck.Unlock() + + ch <- waitResult{txn: tx} + }() + + return ch +} + +func (s *Service) Close() { + ctx, cancel := context.WithTimeout(context.Background(), time.Second) + defer cancel() + if err := s.col.Database().Client().Disconnect(ctx); err != nil { + log.Errorf("disconnecting mongo client: %s", err) + } + log.Info("mongo client disconnected") + + stopped := make(chan struct{}) + go func() { + s.server.GracefulStop() + close(stopped) + }() + t := time.NewTimer(10 * time.Second) + select { + case <-t.C: + s.server.Stop() + case <-stopped: + t.Stop() + } + log.Info("gRPC server stopped") +} + +func (s *Service) updateTxn(ctx context.Context, t txn) error { + res, err := s.col.ReplaceOne(ctx, bson.M{"_id": t.ID}, &t) + if err != nil { + log.Errorf("calling ReplaceOne to update txn: %v", err) + return err + } + if res.MatchedCount == 0 { + log.Error("no document matched calling ReplaceOne to update txn") + return fmt.Errorf("no matched txn document to replace") + } + return nil +} + +func toPbTxn(txn txn) (*pb.Txn, error) { + latestMsgCid, err := txn.latestMsgCid() + if err != nil { + return nil, err + } + return &pb.Txn{ + Id: txn.ID.Hex(), + From: txn.From, + To: txn.To, + Amount: txn.Amount, + MessageCid: latestMsgCid.Cid, + MessageState: txn.MessageState, + Waiting: txn.Waiting, + FailureMsg: txn.FailureMsg, + CreatedAt: timestamppb.New(txn.CreatedAt), + UpdatedAt: timestamppb.New(txn.UpdatedAt), + }, nil +} diff --git a/api/sendfild/service/service_test.go b/api/sendfild/service/service_test.go new file mode 100644 index 000000000..a4fdf8d4b --- /dev/null +++ b/api/sendfild/service/service_test.go @@ -0,0 +1,102 @@ +package service + +import ( + "context" + "net" + "os" + "testing" + "time" + + "github.com/filecoin-project/go-address" + "github.com/filecoin-project/lotus/api/apistruct" + "github.com/filecoin-project/lotus/chain/types" + logging "github.com/ipfs/go-log/v2" + "github.com/stretchr/testify/require" + "github.com/textileio/go-ds-mongo/test" + "github.com/textileio/powergate/v2/tests" + powutil "github.com/textileio/powergate/v2/util" + pb "github.com/textileio/textile/v2/api/sendfild/pb" + "github.com/textileio/textile/v2/util" + "google.golang.org/grpc" + "google.golang.org/grpc/test/bufconn" +) + +const bufSize = 1024 * 1024 + +var ( + ctx, _ = context.WithTimeout(context.Background(), 2*time.Minute) +) + +func TestMain(m *testing.M) { + powutil.AvgBlockTime = time.Millisecond * 100 + logging.SetAllLoggers(logging.LevelError) + + cleanup := func() {} + if os.Getenv("SKIP_SERVICES") != "true" { + cleanup = test.StartMongoDB() + } + exitVal := m.Run() + cleanup() + os.Exit(exitVal) +} + +func TestIt(t *testing.T) { + c, lc, dAddr, cleanup := requireSetup(t, ctx) + defer cleanup() + addr := requireLotusAddress(t, ctx, lc) + res, err := c.SendFil(ctx, &pb.SendFilRequest{From: dAddr.String(), To: addr.String(), Amount: "1000", Wait: false}) + require.NoError(t, err) + require.NotEmpty(t, res.Txn.MessageCid) + infoRes, err := c.Txn(ctx, &pb.TxnRequest{MessageCid: res.Txn.MessageCid, Wait: false}) + require.NoError(t, err) + require.NotNil(t, infoRes) + infoRes2, err := c.Txn(ctx, &pb.TxnRequest{MessageCid: res.Txn.MessageCid, Wait: true}) + require.NoError(t, err) + require.NotNil(t, infoRes2) + infoRes3, err := c.Txn(ctx, &pb.TxnRequest{MessageCid: res.Txn.MessageCid, Wait: true}) + require.NoError(t, err) + require.NotNil(t, infoRes3) +} + +func requireSetup(t *testing.T, ctx context.Context) (pb.SendFilServiceClient, *apistruct.FullNodeStruct, address.Address, func()) { + clientBuilder, addr, _ := tests.CreateLocalDevnet(t, 1) + time.Sleep(time.Millisecond * 500) // Allow the network to some tipsets + + listener := bufconn.Listen(bufSize) + + conf := Config{ + Listener: listener, + ClientBuilder: clientBuilder, + MongoUri: test.GetMongoUri(), + MongoDbName: util.MakeToken(12), + Debug: true, + } + s, err := New(ctx, conf) + require.NoError(t, err) + + bufDialer := func(context.Context, string) (net.Conn, error) { + return listener.Dial() + } + + conn, err := grpc.Dial("bufnet", grpc.WithContextDialer(bufDialer), grpc.WithInsecure()) + require.NoError(t, err) + client := pb.NewSendFilServiceClient(conn) + + lotusClient, closeLotusClient, err := clientBuilder(ctx) + require.NoError(t, err) + + cleanup := func() { + conn.Close() + s.Close() + closeLotusClient() + } + + return client, lotusClient, addr, cleanup +} + +func requireLotusAddress(t *testing.T, ctx context.Context, lotusClient *apistruct.FullNodeStruct) address.Address { + addr, err := lotusClient.WalletNew(ctx, types.KTBLS) + require.NoError(t, err) + require.Greater(t, len(addr.String()), 0) + return addr +} diff --git a/go.mod b/go.mod index d0ed7eec7..107cd8c89 100644 --- a/go.mod +++ b/go.mod @@ -13,7 +13,9 @@ require ( github.com/cloudflare/cloudflare-go v0.11.6 github.com/customerio/go-customerio v2.0.0+incompatible github.com/dgrijalva/jwt-go v3.2.0+incompatible + github.com/filecoin-project/go-address v0.0.5-0.20201103152444-f2023ef3f5bb github.com/filecoin-project/go-fil-markets v1.0.10 + github.com/filecoin-project/lotus v1.4.0 github.com/gin-contrib/location v0.0.2 github.com/gin-contrib/static v0.0.0-20191128031702-f81c604d8ac2 github.com/gin-gonic/gin v1.6.3 diff --git a/go.sum b/go.sum index 965323853..9dde7ac0e 100644 --- a/go.sum +++ b/go.sum @@ -1698,6 +1698,7 @@ github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DM github.com/spf13/viper v1.7.0/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg= github.com/spf13/viper v1.7.1 h1:pM5oEahlgWv/WnHXpgbKz7iLIxRf65tye2Ci+XFK5sk= github.com/spf13/viper v1.7.1/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg= +github.com/src-d/envconfig v1.0.0 h1:/AJi6DtjFhZKNx3OB2qMsq7y4yT5//AeSZIe7rk+PX8= github.com/src-d/envconfig v1.0.0/go.mod h1:Q9YQZ7BKITldTBnoxsE5gOeB5y66RyPXeue/R4aaNBc= github.com/streadway/amqp v0.0.0-20190404075320-75d898a42a94/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw= github.com/streadway/amqp v0.0.0-20190827072141-edfb9018d271/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw= @@ -1823,6 +1824,7 @@ github.com/whyrusleeping/pubsub v0.0.0-20131020042734-02de8aa2db3d/go.mod h1:g7c github.com/whyrusleeping/timecache v0.0.0-20160911033111-cfcb2f1abfee h1:lYbXeSvJi5zk5GLKVuid9TVjS9a0OmLIDKTfoZBL6Ow= github.com/whyrusleeping/timecache v0.0.0-20160911033111-cfcb2f1abfee/go.mod h1:m2aV4LZI4Aez7dP5PMyVKEHhUyEJ/RjmPEDOpDvudHg= github.com/whyrusleeping/yamux v1.1.5/go.mod h1:E8LnQQ8HKx5KD29HZFUwM1PxCOdPRzGwur1mcYhXcD8= +github.com/x-cray/logrus-prefixed-formatter v0.5.2 h1:00txxvfBM9muc0jiLIEAkAcIMJzfthRT6usrui8uGmg= github.com/x-cray/logrus-prefixed-formatter v0.5.2/go.mod h1:2duySbKsL6M18s5GU7VPsoEPHyzalCE06qoARUCeBBE= github.com/xakep666/mongo-migrate v0.2.1 h1:pRK966a44ujuGMEl73MOzv4MajcH8Q6MWo+TBlxjhvs= github.com/xakep666/mongo-migrate v0.2.1/go.mod h1:pVQysP+es2wX4TaeVd7zLkRZhKMcBqcC/KRyLms6Eyk= @@ -2133,6 +2135,7 @@ golang.org/x/sys v0.0.0-20201009025420-dfb3f7c4e634/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20201020230747-6e5568b54d1a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201218084310-7d0127a74742 h1:+CBz4km/0KPU3RGTwARGh/noP3bEwtHcq+0YcBQM2JQ= golang.org/x/sys v0.0.0-20201218084310-7d0127a74742/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/term v0.0.0-20201117132131-f5c789dd3221 h1:/ZHdbVpdR/jk3g30/d4yUL0JU9kksj8+F/bnQUVLGDM= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -2317,6 +2320,7 @@ gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= gopkg.in/segmentio/analytics-go.v3 v3.1.0 h1:UzxH1uaGZRpMKDhJyBz0pexz6yUoBU3x8bJsRk/HV6U= gopkg.in/segmentio/analytics-go.v3 v3.1.0/go.mod h1:4QqqlTlSSpVlWA9/9nDcPw+FkM2yv1NQoYjUbL9/JAw= gopkg.in/src-d/go-cli.v0 v0.0.0-20181105080154-d492247bbc0d/go.mod h1:z+K8VcOYVYcSwSjGebuDL6176A1XskgbtNl64NSg+n8= +gopkg.in/src-d/go-log.v1 v1.0.1 h1:heWvX7J6qbGWbeFS/aRmiy1eYaT+QMV6wNvHDyMjQV4= gopkg.in/src-d/go-log.v1 v1.0.1/go.mod h1:GN34hKP0g305ysm2/hctJ0Y8nWP3zxXXJ8GFabTyABE= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= From 6585907ff6a11b12767b7bd86ab7062aef01feef Mon Sep 17 00:00:00 2001 From: Aaron Sutula Date: Fri, 26 Feb 2021 12:19:21 -0600 Subject: [PATCH 02/16] nanofil, list and summary apis Signed-off-by: Aaron Sutula --- api/sendfild/pb/sendfil.pb.go | 870 ++++++++++++++++++++++++--- api/sendfild/pb/sendfil.proto | 57 +- api/sendfild/service/service.go | 292 ++++++++- api/sendfild/service/service_test.go | 18 +- 4 files changed, 1129 insertions(+), 108 deletions(-) diff --git a/api/sendfild/pb/sendfil.pb.go b/api/sendfild/pb/sendfil.pb.go index 63e22acf0..43af195be 100644 --- a/api/sendfild/pb/sendfil.pb.go +++ b/api/sendfild/pb/sendfil.pb.go @@ -82,21 +82,70 @@ func (MessageState) EnumDescriptor() ([]byte, []int) { return file_api_sendfild_pb_sendfil_proto_rawDescGZIP(), []int{0} } +type WaitingFilter int32 + +const ( + WaitingFilter_WAITING_FILTER_UNSPECIFIED WaitingFilter = 0 + WaitingFilter_WAITING_FILTER_WAITING WaitingFilter = 1 + WaitingFilter_WAITING_FILTER_NOT_WAITING WaitingFilter = 2 +) + +// Enum value maps for WaitingFilter. +var ( + WaitingFilter_name = map[int32]string{ + 0: "WAITING_FILTER_UNSPECIFIED", + 1: "WAITING_FILTER_WAITING", + 2: "WAITING_FILTER_NOT_WAITING", + } + WaitingFilter_value = map[string]int32{ + "WAITING_FILTER_UNSPECIFIED": 0, + "WAITING_FILTER_WAITING": 1, + "WAITING_FILTER_NOT_WAITING": 2, + } +) + +func (x WaitingFilter) Enum() *WaitingFilter { + p := new(WaitingFilter) + *p = x + return p +} + +func (x WaitingFilter) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (WaitingFilter) Descriptor() protoreflect.EnumDescriptor { + return file_api_sendfild_pb_sendfil_proto_enumTypes[1].Descriptor() +} + +func (WaitingFilter) Type() protoreflect.EnumType { + return &file_api_sendfild_pb_sendfil_proto_enumTypes[1] +} + +func (x WaitingFilter) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use WaitingFilter.Descriptor instead. +func (WaitingFilter) EnumDescriptor() ([]byte, []int) { + return file_api_sendfild_pb_sendfil_proto_rawDescGZIP(), []int{1} +} + type Txn struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` - From string `protobuf:"bytes,2,opt,name=from,proto3" json:"from,omitempty"` - To string `protobuf:"bytes,3,opt,name=to,proto3" json:"to,omitempty"` - Amount string `protobuf:"bytes,4,opt,name=amount,proto3" json:"amount,omitempty"` - MessageCid string `protobuf:"bytes,5,opt,name=message_cid,json=messageCid,proto3" json:"message_cid,omitempty"` - MessageState MessageState `protobuf:"varint,6,opt,name=message_state,json=messageState,proto3,enum=api.sendfild.pb.MessageState" json:"message_state,omitempty"` - Waiting bool `protobuf:"varint,7,opt,name=waiting,proto3" json:"waiting,omitempty"` - FailureMsg string `protobuf:"bytes,8,opt,name=failure_msg,json=failureMsg,proto3" json:"failure_msg,omitempty"` - CreatedAt *timestamp.Timestamp `protobuf:"bytes,9,opt,name=created_at,json=createdAt,proto3" json:"created_at,omitempty"` - UpdatedAt *timestamp.Timestamp `protobuf:"bytes,10,opt,name=updated_at,json=updatedAt,proto3" json:"updated_at,omitempty"` + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + From string `protobuf:"bytes,2,opt,name=from,proto3" json:"from,omitempty"` + To string `protobuf:"bytes,3,opt,name=to,proto3" json:"to,omitempty"` + AmountNanoFil int64 `protobuf:"varint,4,opt,name=amount_nano_fil,json=amountNanoFil,proto3" json:"amount_nano_fil,omitempty"` + MessageCid string `protobuf:"bytes,5,opt,name=message_cid,json=messageCid,proto3" json:"message_cid,omitempty"` + MessageState MessageState `protobuf:"varint,6,opt,name=message_state,json=messageState,proto3,enum=api.sendfild.pb.MessageState" json:"message_state,omitempty"` + Waiting bool `protobuf:"varint,7,opt,name=waiting,proto3" json:"waiting,omitempty"` + FailureMsg string `protobuf:"bytes,8,opt,name=failure_msg,json=failureMsg,proto3" json:"failure_msg,omitempty"` + CreatedAt *timestamp.Timestamp `protobuf:"bytes,9,opt,name=created_at,json=createdAt,proto3" json:"created_at,omitempty"` + UpdatedAt *timestamp.Timestamp `protobuf:"bytes,10,opt,name=updated_at,json=updatedAt,proto3" json:"updated_at,omitempty"` } func (x *Txn) Reset() { @@ -152,11 +201,11 @@ func (x *Txn) GetTo() string { return "" } -func (x *Txn) GetAmount() string { +func (x *Txn) GetAmountNanoFil() int64 { if x != nil { - return x.Amount + return x.AmountNanoFil } - return "" + return 0 } func (x *Txn) GetMessageCid() string { @@ -206,10 +255,10 @@ type SendFilRequest struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - From string `protobuf:"bytes,1,opt,name=from,proto3" json:"from,omitempty"` - To string `protobuf:"bytes,2,opt,name=to,proto3" json:"to,omitempty"` - Amount string `protobuf:"bytes,3,opt,name=amount,proto3" json:"amount,omitempty"` - Wait bool `protobuf:"varint,4,opt,name=wait,proto3" json:"wait,omitempty"` + From string `protobuf:"bytes,1,opt,name=from,proto3" json:"from,omitempty"` + To string `protobuf:"bytes,2,opt,name=to,proto3" json:"to,omitempty"` + AmountNanoFil int64 `protobuf:"varint,3,opt,name=amount_nano_fil,json=amountNanoFil,proto3" json:"amount_nano_fil,omitempty"` + Wait bool `protobuf:"varint,4,opt,name=wait,proto3" json:"wait,omitempty"` } func (x *SendFilRequest) Reset() { @@ -258,11 +307,11 @@ func (x *SendFilRequest) GetTo() string { return "" } -func (x *SendFilRequest) GetAmount() string { +func (x *SendFilRequest) GetAmountNanoFil() int64 { if x != nil { - return x.Amount + return x.AmountNanoFil } - return "" + return 0 } func (x *SendFilRequest) GetWait() bool { @@ -421,6 +470,426 @@ func (x *TxnResponse) GetTxn() *Txn { return nil } +type ListTxnsRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + FromFilter string `protobuf:"bytes,1,opt,name=from_filter,json=fromFilter,proto3" json:"from_filter,omitempty"` + ToFilter string `protobuf:"bytes,2,opt,name=to_filter,json=toFilter,proto3" json:"to_filter,omitempty"` + InvolvingFilter string `protobuf:"bytes,3,opt,name=involving_filter,json=involvingFilter,proto3" json:"involving_filter,omitempty"` + AmountNanoFilLtFilter int64 `protobuf:"varint,4,opt,name=amount_nano_fil_lt_filter,json=amountNanoFilLtFilter,proto3" json:"amount_nano_fil_lt_filter,omitempty"` + AmountNanoFilGtFilter int64 `protobuf:"varint,5,opt,name=amount_nano_fil_gt_filter,json=amountNanoFilGtFilter,proto3" json:"amount_nano_fil_gt_filter,omitempty"` + AmountNanoFilLteqFilter int64 `protobuf:"varint,6,opt,name=amount_nano_fil_lteq_filter,json=amountNanoFilLteqFilter,proto3" json:"amount_nano_fil_lteq_filter,omitempty"` + AmountNanoFilGteqFilter int64 `protobuf:"varint,7,opt,name=amount_nano_fil_gteq_filter,json=amountNanoFilGteqFilter,proto3" json:"amount_nano_fil_gteq_filter,omitempty"` + AmountNanoFilEqFilter int64 `protobuf:"varint,8,opt,name=amount_nano_fil_eq_filter,json=amountNanoFilEqFilter,proto3" json:"amount_nano_fil_eq_filter,omitempty"` + MessageStateFilter MessageState `protobuf:"varint,9,opt,name=message_state_filter,json=messageStateFilter,proto3,enum=api.sendfild.pb.MessageState" json:"message_state_filter,omitempty"` + WaitingFilter WaitingFilter `protobuf:"varint,10,opt,name=waiting_filter,json=waitingFilter,proto3,enum=api.sendfild.pb.WaitingFilter" json:"waiting_filter,omitempty"` + CreatedBefore *timestamp.Timestamp `protobuf:"bytes,11,opt,name=created_before,json=createdBefore,proto3" json:"created_before,omitempty"` + CreatedAfter *timestamp.Timestamp `protobuf:"bytes,12,opt,name=created_after,json=createdAfter,proto3" json:"created_after,omitempty"` + UpdatedBefore *timestamp.Timestamp `protobuf:"bytes,13,opt,name=updated_before,json=updatedBefore,proto3" json:"updated_before,omitempty"` + UpdatedAfter *timestamp.Timestamp `protobuf:"bytes,14,opt,name=updated_after,json=updatedAfter,proto3" json:"updated_after,omitempty"` + Ascending bool `protobuf:"varint,15,opt,name=ascending,proto3" json:"ascending,omitempty"` + MoreToken int64 `protobuf:"varint,16,opt,name=more_token,json=moreToken,proto3" json:"more_token,omitempty"` + Limit int64 `protobuf:"varint,17,opt,name=limit,proto3" json:"limit,omitempty"` +} + +func (x *ListTxnsRequest) Reset() { + *x = ListTxnsRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_api_sendfild_pb_sendfil_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ListTxnsRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListTxnsRequest) ProtoMessage() {} + +func (x *ListTxnsRequest) ProtoReflect() protoreflect.Message { + mi := &file_api_sendfild_pb_sendfil_proto_msgTypes[5] + 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 ListTxnsRequest.ProtoReflect.Descriptor instead. +func (*ListTxnsRequest) Descriptor() ([]byte, []int) { + return file_api_sendfild_pb_sendfil_proto_rawDescGZIP(), []int{5} +} + +func (x *ListTxnsRequest) GetFromFilter() string { + if x != nil { + return x.FromFilter + } + return "" +} + +func (x *ListTxnsRequest) GetToFilter() string { + if x != nil { + return x.ToFilter + } + return "" +} + +func (x *ListTxnsRequest) GetInvolvingFilter() string { + if x != nil { + return x.InvolvingFilter + } + return "" +} + +func (x *ListTxnsRequest) GetAmountNanoFilLtFilter() int64 { + if x != nil { + return x.AmountNanoFilLtFilter + } + return 0 +} + +func (x *ListTxnsRequest) GetAmountNanoFilGtFilter() int64 { + if x != nil { + return x.AmountNanoFilGtFilter + } + return 0 +} + +func (x *ListTxnsRequest) GetAmountNanoFilLteqFilter() int64 { + if x != nil { + return x.AmountNanoFilLteqFilter + } + return 0 +} + +func (x *ListTxnsRequest) GetAmountNanoFilGteqFilter() int64 { + if x != nil { + return x.AmountNanoFilGteqFilter + } + return 0 +} + +func (x *ListTxnsRequest) GetAmountNanoFilEqFilter() int64 { + if x != nil { + return x.AmountNanoFilEqFilter + } + return 0 +} + +func (x *ListTxnsRequest) GetMessageStateFilter() MessageState { + if x != nil { + return x.MessageStateFilter + } + return MessageState_MESSAGE_STATE_UNSPECIFIED +} + +func (x *ListTxnsRequest) GetWaitingFilter() WaitingFilter { + if x != nil { + return x.WaitingFilter + } + return WaitingFilter_WAITING_FILTER_UNSPECIFIED +} + +func (x *ListTxnsRequest) GetCreatedBefore() *timestamp.Timestamp { + if x != nil { + return x.CreatedBefore + } + return nil +} + +func (x *ListTxnsRequest) GetCreatedAfter() *timestamp.Timestamp { + if x != nil { + return x.CreatedAfter + } + return nil +} + +func (x *ListTxnsRequest) GetUpdatedBefore() *timestamp.Timestamp { + if x != nil { + return x.UpdatedBefore + } + return nil +} + +func (x *ListTxnsRequest) GetUpdatedAfter() *timestamp.Timestamp { + if x != nil { + return x.UpdatedAfter + } + return nil +} + +func (x *ListTxnsRequest) GetAscending() bool { + if x != nil { + return x.Ascending + } + return false +} + +func (x *ListTxnsRequest) GetMoreToken() int64 { + if x != nil { + return x.MoreToken + } + return 0 +} + +func (x *ListTxnsRequest) GetLimit() int64 { + if x != nil { + return x.Limit + } + return 0 +} + +type ListTxnsResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Txns []*Txn `protobuf:"bytes,1,rep,name=txns,proto3" json:"txns,omitempty"` + More bool `protobuf:"varint,2,opt,name=more,proto3" json:"more,omitempty"` + MoreToken int64 `protobuf:"varint,3,opt,name=more_token,json=moreToken,proto3" json:"more_token,omitempty"` +} + +func (x *ListTxnsResponse) Reset() { + *x = ListTxnsResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_api_sendfild_pb_sendfil_proto_msgTypes[6] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ListTxnsResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListTxnsResponse) ProtoMessage() {} + +func (x *ListTxnsResponse) ProtoReflect() protoreflect.Message { + mi := &file_api_sendfild_pb_sendfil_proto_msgTypes[6] + 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 ListTxnsResponse.ProtoReflect.Descriptor instead. +func (*ListTxnsResponse) Descriptor() ([]byte, []int) { + return file_api_sendfild_pb_sendfil_proto_rawDescGZIP(), []int{6} +} + +func (x *ListTxnsResponse) GetTxns() []*Txn { + if x != nil { + return x.Txns + } + return nil +} + +func (x *ListTxnsResponse) GetMore() bool { + if x != nil { + return x.More + } + return false +} + +func (x *ListTxnsResponse) GetMoreToken() int64 { + if x != nil { + return x.MoreToken + } + return 0 +} + +type SummaryRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Since *timestamp.Timestamp `protobuf:"bytes,1,opt,name=since,proto3" json:"since,omitempty"` + Before *timestamp.Timestamp `protobuf:"bytes,2,opt,name=before,proto3" json:"before,omitempty"` +} + +func (x *SummaryRequest) Reset() { + *x = SummaryRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_api_sendfild_pb_sendfil_proto_msgTypes[7] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *SummaryRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SummaryRequest) ProtoMessage() {} + +func (x *SummaryRequest) ProtoReflect() protoreflect.Message { + mi := &file_api_sendfild_pb_sendfil_proto_msgTypes[7] + 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 SummaryRequest.ProtoReflect.Descriptor instead. +func (*SummaryRequest) Descriptor() ([]byte, []int) { + return file_api_sendfild_pb_sendfil_proto_rawDescGZIP(), []int{7} +} + +func (x *SummaryRequest) GetSince() *timestamp.Timestamp { + if x != nil { + return x.Since + } + return nil +} + +func (x *SummaryRequest) GetBefore() *timestamp.Timestamp { + if x != nil { + return x.Before + } + return nil +} + +type SummaryResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + CountTxns int64 `protobuf:"varint,1,opt,name=count_txns,json=countTxns,proto3" json:"count_txns,omitempty"` + CountPending int64 `protobuf:"varint,2,opt,name=count_pending,json=countPending,proto3" json:"count_pending,omitempty"` + CountActive int64 `protobuf:"varint,3,opt,name=count_active,json=countActive,proto3" json:"count_active,omitempty"` + CountFailed int64 `protobuf:"varint,4,opt,name=count_failed,json=countFailed,proto3" json:"count_failed,omitempty"` + CountWaiting int64 `protobuf:"varint,5,opt,name=count_waiting,json=countWaiting,proto3" json:"count_waiting,omitempty"` + CountFromAddrs int64 `protobuf:"varint,6,opt,name=count_from_addrs,json=countFromAddrs,proto3" json:"count_from_addrs,omitempty"` + CountToAddrs int64 `protobuf:"varint,7,opt,name=count_to_addrs,json=countToAddrs,proto3" json:"count_to_addrs,omitempty"` + TotalNanoFilSent int64 `protobuf:"varint,8,opt,name=total_nano_fil_sent,json=totalNanoFilSent,proto3" json:"total_nano_fil_sent,omitempty"` + AvgNanoFilSent float32 `protobuf:"fixed32,9,opt,name=avg_nano_fil_sent,json=avgNanoFilSent,proto3" json:"avg_nano_fil_sent,omitempty"` + MaxNanoFilSent int64 `protobuf:"varint,10,opt,name=max_nano_fil_sent,json=maxNanoFilSent,proto3" json:"max_nano_fil_sent,omitempty"` + MinNanoFilSent int64 `protobuf:"varint,11,opt,name=min_nano_fil_sent,json=minNanoFilSent,proto3" json:"min_nano_fil_sent,omitempty"` +} + +func (x *SummaryResponse) Reset() { + *x = SummaryResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_api_sendfild_pb_sendfil_proto_msgTypes[8] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *SummaryResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SummaryResponse) ProtoMessage() {} + +func (x *SummaryResponse) ProtoReflect() protoreflect.Message { + mi := &file_api_sendfild_pb_sendfil_proto_msgTypes[8] + 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 SummaryResponse.ProtoReflect.Descriptor instead. +func (*SummaryResponse) Descriptor() ([]byte, []int) { + return file_api_sendfild_pb_sendfil_proto_rawDescGZIP(), []int{8} +} + +func (x *SummaryResponse) GetCountTxns() int64 { + if x != nil { + return x.CountTxns + } + return 0 +} + +func (x *SummaryResponse) GetCountPending() int64 { + if x != nil { + return x.CountPending + } + return 0 +} + +func (x *SummaryResponse) GetCountActive() int64 { + if x != nil { + return x.CountActive + } + return 0 +} + +func (x *SummaryResponse) GetCountFailed() int64 { + if x != nil { + return x.CountFailed + } + return 0 +} + +func (x *SummaryResponse) GetCountWaiting() int64 { + if x != nil { + return x.CountWaiting + } + return 0 +} + +func (x *SummaryResponse) GetCountFromAddrs() int64 { + if x != nil { + return x.CountFromAddrs + } + return 0 +} + +func (x *SummaryResponse) GetCountToAddrs() int64 { + if x != nil { + return x.CountToAddrs + } + return 0 +} + +func (x *SummaryResponse) GetTotalNanoFilSent() int64 { + if x != nil { + return x.TotalNanoFilSent + } + return 0 +} + +func (x *SummaryResponse) GetAvgNanoFilSent() float32 { + if x != nil { + return x.AvgNanoFilSent + } + return 0 +} + +func (x *SummaryResponse) GetMaxNanoFilSent() int64 { + if x != nil { + return x.MaxNanoFilSent + } + return 0 +} + +func (x *SummaryResponse) GetMinNanoFilSent() int64 { + if x != nil { + return x.MinNanoFilSent + } + return 0 +} + var File_api_sendfild_pb_sendfil_proto protoreflect.FileDescriptor var file_api_sendfild_pb_sendfil_proto_rawDesc = []byte{ @@ -429,12 +898,13 @@ var file_api_sendfild_pb_sendfil_proto_rawDesc = []byte{ 0x0f, 0x61, 0x70, 0x69, 0x2e, 0x73, 0x65, 0x6e, 0x64, 0x66, 0x69, 0x6c, 0x64, 0x2e, 0x70, 0x62, 0x1a, 0x1f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x22, 0xe7, 0x02, 0x0a, 0x03, 0x54, 0x78, 0x6e, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, + 0x6f, 0x22, 0xf7, 0x02, 0x0a, 0x03, 0x54, 0x78, 0x6e, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x66, 0x72, 0x6f, 0x6d, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x66, 0x72, 0x6f, 0x6d, 0x12, 0x0e, 0x0a, - 0x02, 0x74, 0x6f, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x74, 0x6f, 0x12, 0x16, 0x0a, - 0x06, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x61, - 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x1f, 0x0a, 0x0b, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, + 0x02, 0x74, 0x6f, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x74, 0x6f, 0x12, 0x26, 0x0a, + 0x0f, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x6e, 0x61, 0x6e, 0x6f, 0x5f, 0x66, 0x69, 0x6c, + 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0d, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x4e, 0x61, + 0x6e, 0x6f, 0x46, 0x69, 0x6c, 0x12, 0x1f, 0x0a, 0x0b, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x5f, 0x63, 0x69, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x43, 0x69, 0x64, 0x12, 0x42, 0x0a, 0x0d, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1d, 0x2e, @@ -451,12 +921,13 @@ var file_api_sendfild_pb_sendfil_proto_rawDesc = []byte{ 0x12, 0x39, 0x0a, 0x0a, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, - 0x52, 0x09, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x22, 0x60, 0x0a, 0x0e, 0x53, + 0x52, 0x09, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x22, 0x70, 0x0a, 0x0e, 0x53, 0x65, 0x6e, 0x64, 0x46, 0x69, 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x66, 0x72, 0x6f, 0x6d, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x66, 0x72, 0x6f, 0x6d, 0x12, 0x0e, 0x0a, 0x02, 0x74, 0x6f, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x74, - 0x6f, 0x12, 0x16, 0x0a, 0x06, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x06, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x77, 0x61, 0x69, + 0x6f, 0x12, 0x26, 0x0a, 0x0f, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x6e, 0x61, 0x6e, 0x6f, + 0x5f, 0x66, 0x69, 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0d, 0x61, 0x6d, 0x6f, 0x75, + 0x6e, 0x74, 0x4e, 0x61, 0x6e, 0x6f, 0x46, 0x69, 0x6c, 0x12, 0x12, 0x0a, 0x04, 0x77, 0x61, 0x69, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x04, 0x77, 0x61, 0x69, 0x74, 0x22, 0x39, 0x0a, 0x0f, 0x53, 0x65, 0x6e, 0x64, 0x46, 0x69, 0x6c, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x26, 0x0a, 0x03, 0x74, 0x78, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, @@ -469,29 +940,146 @@ var file_api_sendfild_pb_sendfil_proto_rawDesc = []byte{ 0x78, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x26, 0x0a, 0x03, 0x74, 0x78, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x73, 0x65, 0x6e, 0x64, 0x66, 0x69, 0x6c, 0x64, 0x2e, 0x70, 0x62, 0x2e, 0x54, 0x78, 0x6e, 0x52, 0x03, 0x74, - 0x78, 0x6e, 0x2a, 0x7c, 0x0a, 0x0c, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x53, 0x74, 0x61, - 0x74, 0x65, 0x12, 0x1d, 0x0a, 0x19, 0x4d, 0x45, 0x53, 0x53, 0x41, 0x47, 0x45, 0x5f, 0x53, 0x54, - 0x41, 0x54, 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, - 0x00, 0x12, 0x19, 0x0a, 0x15, 0x4d, 0x45, 0x53, 0x53, 0x41, 0x47, 0x45, 0x5f, 0x53, 0x54, 0x41, - 0x54, 0x45, 0x5f, 0x50, 0x45, 0x4e, 0x44, 0x49, 0x4e, 0x47, 0x10, 0x01, 0x12, 0x18, 0x0a, 0x14, - 0x4d, 0x45, 0x53, 0x53, 0x41, 0x47, 0x45, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x45, 0x5f, 0x41, 0x43, - 0x54, 0x49, 0x56, 0x45, 0x10, 0x02, 0x12, 0x18, 0x0a, 0x14, 0x4d, 0x45, 0x53, 0x53, 0x41, 0x47, - 0x45, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x45, 0x5f, 0x46, 0x41, 0x49, 0x4c, 0x45, 0x44, 0x10, 0x03, - 0x32, 0xa4, 0x01, 0x0a, 0x0e, 0x53, 0x65, 0x6e, 0x64, 0x46, 0x69, 0x6c, 0x53, 0x65, 0x72, 0x76, - 0x69, 0x63, 0x65, 0x12, 0x4e, 0x0a, 0x07, 0x53, 0x65, 0x6e, 0x64, 0x46, 0x69, 0x6c, 0x12, 0x1f, + 0x78, 0x6e, 0x22, 0x97, 0x07, 0x0a, 0x0f, 0x4c, 0x69, 0x73, 0x74, 0x54, 0x78, 0x6e, 0x73, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1f, 0x0a, 0x0b, 0x66, 0x72, 0x6f, 0x6d, 0x5f, 0x66, + 0x69, 0x6c, 0x74, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x66, 0x72, 0x6f, + 0x6d, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x12, 0x1b, 0x0a, 0x09, 0x74, 0x6f, 0x5f, 0x66, 0x69, + 0x6c, 0x74, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x74, 0x6f, 0x46, 0x69, + 0x6c, 0x74, 0x65, 0x72, 0x12, 0x29, 0x0a, 0x10, 0x69, 0x6e, 0x76, 0x6f, 0x6c, 0x76, 0x69, 0x6e, + 0x67, 0x5f, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, + 0x69, 0x6e, 0x76, 0x6f, 0x6c, 0x76, 0x69, 0x6e, 0x67, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x12, + 0x38, 0x0a, 0x19, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x6e, 0x61, 0x6e, 0x6f, 0x5f, 0x66, + 0x69, 0x6c, 0x5f, 0x6c, 0x74, 0x5f, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x18, 0x04, 0x20, 0x01, + 0x28, 0x03, 0x52, 0x15, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x4e, 0x61, 0x6e, 0x6f, 0x46, 0x69, + 0x6c, 0x4c, 0x74, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x12, 0x38, 0x0a, 0x19, 0x61, 0x6d, 0x6f, + 0x75, 0x6e, 0x74, 0x5f, 0x6e, 0x61, 0x6e, 0x6f, 0x5f, 0x66, 0x69, 0x6c, 0x5f, 0x67, 0x74, 0x5f, + 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, 0x52, 0x15, 0x61, 0x6d, + 0x6f, 0x75, 0x6e, 0x74, 0x4e, 0x61, 0x6e, 0x6f, 0x46, 0x69, 0x6c, 0x47, 0x74, 0x46, 0x69, 0x6c, + 0x74, 0x65, 0x72, 0x12, 0x3c, 0x0a, 0x1b, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x6e, 0x61, + 0x6e, 0x6f, 0x5f, 0x66, 0x69, 0x6c, 0x5f, 0x6c, 0x74, 0x65, 0x71, 0x5f, 0x66, 0x69, 0x6c, 0x74, + 0x65, 0x72, 0x18, 0x06, 0x20, 0x01, 0x28, 0x03, 0x52, 0x17, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, + 0x4e, 0x61, 0x6e, 0x6f, 0x46, 0x69, 0x6c, 0x4c, 0x74, 0x65, 0x71, 0x46, 0x69, 0x6c, 0x74, 0x65, + 0x72, 0x12, 0x3c, 0x0a, 0x1b, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x6e, 0x61, 0x6e, 0x6f, + 0x5f, 0x66, 0x69, 0x6c, 0x5f, 0x67, 0x74, 0x65, 0x71, 0x5f, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, + 0x18, 0x07, 0x20, 0x01, 0x28, 0x03, 0x52, 0x17, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x4e, 0x61, + 0x6e, 0x6f, 0x46, 0x69, 0x6c, 0x47, 0x74, 0x65, 0x71, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x12, + 0x38, 0x0a, 0x19, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x6e, 0x61, 0x6e, 0x6f, 0x5f, 0x66, + 0x69, 0x6c, 0x5f, 0x65, 0x71, 0x5f, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x18, 0x08, 0x20, 0x01, + 0x28, 0x03, 0x52, 0x15, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x4e, 0x61, 0x6e, 0x6f, 0x46, 0x69, + 0x6c, 0x45, 0x71, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x12, 0x4f, 0x0a, 0x14, 0x6d, 0x65, 0x73, + 0x73, 0x61, 0x67, 0x65, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x5f, 0x66, 0x69, 0x6c, 0x74, 0x65, + 0x72, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1d, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x73, 0x65, + 0x6e, 0x64, 0x66, 0x69, 0x6c, 0x64, 0x2e, 0x70, 0x62, 0x2e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, + 0x65, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x12, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x53, + 0x74, 0x61, 0x74, 0x65, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x12, 0x45, 0x0a, 0x0e, 0x77, 0x61, + 0x69, 0x74, 0x69, 0x6e, 0x67, 0x5f, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x18, 0x0a, 0x20, 0x01, + 0x28, 0x0e, 0x32, 0x1e, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x73, 0x65, 0x6e, 0x64, 0x66, 0x69, 0x6c, + 0x64, 0x2e, 0x70, 0x62, 0x2e, 0x57, 0x61, 0x69, 0x74, 0x69, 0x6e, 0x67, 0x46, 0x69, 0x6c, 0x74, + 0x65, 0x72, 0x52, 0x0d, 0x77, 0x61, 0x69, 0x74, 0x69, 0x6e, 0x67, 0x46, 0x69, 0x6c, 0x74, 0x65, + 0x72, 0x12, 0x41, 0x0a, 0x0e, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x62, 0x65, 0x66, + 0x6f, 0x72, 0x65, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, + 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, + 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x0d, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x42, 0x65, + 0x66, 0x6f, 0x72, 0x65, 0x12, 0x3f, 0x0a, 0x0d, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, + 0x61, 0x66, 0x74, 0x65, 0x72, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, + 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, + 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x0c, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, + 0x41, 0x66, 0x74, 0x65, 0x72, 0x12, 0x41, 0x0a, 0x0e, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, + 0x5f, 0x62, 0x65, 0x66, 0x6f, 0x72, 0x65, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, + 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, + 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x0d, 0x75, 0x70, 0x64, 0x61, 0x74, + 0x65, 0x64, 0x42, 0x65, 0x66, 0x6f, 0x72, 0x65, 0x12, 0x3f, 0x0a, 0x0d, 0x75, 0x70, 0x64, 0x61, + 0x74, 0x65, 0x64, 0x5f, 0x61, 0x66, 0x74, 0x65, 0x72, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, + 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x0c, 0x75, 0x70, 0x64, + 0x61, 0x74, 0x65, 0x64, 0x41, 0x66, 0x74, 0x65, 0x72, 0x12, 0x1c, 0x0a, 0x09, 0x61, 0x73, 0x63, + 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x61, 0x73, + 0x63, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x12, 0x1d, 0x0a, 0x0a, 0x6d, 0x6f, 0x72, 0x65, 0x5f, + 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x10, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x6d, 0x6f, 0x72, + 0x65, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x14, 0x0a, 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x18, + 0x11, 0x20, 0x01, 0x28, 0x03, 0x52, 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x22, 0x6f, 0x0a, 0x10, + 0x4c, 0x69, 0x73, 0x74, 0x54, 0x78, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x12, 0x28, 0x0a, 0x04, 0x74, 0x78, 0x6e, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x73, 0x65, 0x6e, 0x64, 0x66, 0x69, 0x6c, 0x64, 0x2e, 0x70, 0x62, - 0x2e, 0x53, 0x65, 0x6e, 0x64, 0x46, 0x69, 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, - 0x20, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x73, 0x65, 0x6e, 0x64, 0x66, 0x69, 0x6c, 0x64, 0x2e, 0x70, - 0x62, 0x2e, 0x53, 0x65, 0x6e, 0x64, 0x46, 0x69, 0x6c, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x22, 0x00, 0x12, 0x42, 0x0a, 0x03, 0x54, 0x78, 0x6e, 0x12, 0x1b, 0x2e, 0x61, 0x70, 0x69, + 0x2e, 0x54, 0x78, 0x6e, 0x52, 0x04, 0x74, 0x78, 0x6e, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x6d, 0x6f, + 0x72, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x04, 0x6d, 0x6f, 0x72, 0x65, 0x12, 0x1d, + 0x0a, 0x0a, 0x6d, 0x6f, 0x72, 0x65, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x03, 0x52, 0x09, 0x6d, 0x6f, 0x72, 0x65, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0x76, 0x0a, + 0x0e, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, + 0x30, 0x0a, 0x05, 0x73, 0x69, 0x6e, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, + 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, + 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x05, 0x73, 0x69, 0x6e, 0x63, + 0x65, 0x12, 0x32, 0x0a, 0x06, 0x62, 0x65, 0x66, 0x6f, 0x72, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x06, 0x62, + 0x65, 0x66, 0x6f, 0x72, 0x65, 0x22, 0xc0, 0x03, 0x0a, 0x0f, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, + 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x63, 0x6f, 0x75, + 0x6e, 0x74, 0x5f, 0x74, 0x78, 0x6e, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x63, + 0x6f, 0x75, 0x6e, 0x74, 0x54, 0x78, 0x6e, 0x73, 0x12, 0x23, 0x0a, 0x0d, 0x63, 0x6f, 0x75, 0x6e, + 0x74, 0x5f, 0x70, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, + 0x0c, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x50, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x12, 0x21, 0x0a, + 0x0c, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x03, 0x52, 0x0b, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x41, 0x63, 0x74, 0x69, 0x76, 0x65, + 0x12, 0x21, 0x0a, 0x0c, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x66, 0x61, 0x69, 0x6c, 0x65, 0x64, + 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0b, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x46, 0x61, 0x69, + 0x6c, 0x65, 0x64, 0x12, 0x23, 0x0a, 0x0d, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x77, 0x61, 0x69, + 0x74, 0x69, 0x6e, 0x67, 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0c, 0x63, 0x6f, 0x75, 0x6e, + 0x74, 0x57, 0x61, 0x69, 0x74, 0x69, 0x6e, 0x67, 0x12, 0x28, 0x0a, 0x10, 0x63, 0x6f, 0x75, 0x6e, + 0x74, 0x5f, 0x66, 0x72, 0x6f, 0x6d, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x73, 0x18, 0x06, 0x20, 0x01, + 0x28, 0x03, 0x52, 0x0e, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x46, 0x72, 0x6f, 0x6d, 0x41, 0x64, 0x64, + 0x72, 0x73, 0x12, 0x24, 0x0a, 0x0e, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x74, 0x6f, 0x5f, 0x61, + 0x64, 0x64, 0x72, 0x73, 0x18, 0x07, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0c, 0x63, 0x6f, 0x75, 0x6e, + 0x74, 0x54, 0x6f, 0x41, 0x64, 0x64, 0x72, 0x73, 0x12, 0x2d, 0x0a, 0x13, 0x74, 0x6f, 0x74, 0x61, + 0x6c, 0x5f, 0x6e, 0x61, 0x6e, 0x6f, 0x5f, 0x66, 0x69, 0x6c, 0x5f, 0x73, 0x65, 0x6e, 0x74, 0x18, + 0x08, 0x20, 0x01, 0x28, 0x03, 0x52, 0x10, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x4e, 0x61, 0x6e, 0x6f, + 0x46, 0x69, 0x6c, 0x53, 0x65, 0x6e, 0x74, 0x12, 0x29, 0x0a, 0x11, 0x61, 0x76, 0x67, 0x5f, 0x6e, + 0x61, 0x6e, 0x6f, 0x5f, 0x66, 0x69, 0x6c, 0x5f, 0x73, 0x65, 0x6e, 0x74, 0x18, 0x09, 0x20, 0x01, + 0x28, 0x02, 0x52, 0x0e, 0x61, 0x76, 0x67, 0x4e, 0x61, 0x6e, 0x6f, 0x46, 0x69, 0x6c, 0x53, 0x65, + 0x6e, 0x74, 0x12, 0x29, 0x0a, 0x11, 0x6d, 0x61, 0x78, 0x5f, 0x6e, 0x61, 0x6e, 0x6f, 0x5f, 0x66, + 0x69, 0x6c, 0x5f, 0x73, 0x65, 0x6e, 0x74, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0e, 0x6d, + 0x61, 0x78, 0x4e, 0x61, 0x6e, 0x6f, 0x46, 0x69, 0x6c, 0x53, 0x65, 0x6e, 0x74, 0x12, 0x29, 0x0a, + 0x11, 0x6d, 0x69, 0x6e, 0x5f, 0x6e, 0x61, 0x6e, 0x6f, 0x5f, 0x66, 0x69, 0x6c, 0x5f, 0x73, 0x65, + 0x6e, 0x74, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0e, 0x6d, 0x69, 0x6e, 0x4e, 0x61, 0x6e, + 0x6f, 0x46, 0x69, 0x6c, 0x53, 0x65, 0x6e, 0x74, 0x2a, 0x7c, 0x0a, 0x0c, 0x4d, 0x65, 0x73, 0x73, + 0x61, 0x67, 0x65, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x1d, 0x0a, 0x19, 0x4d, 0x45, 0x53, 0x53, + 0x41, 0x47, 0x45, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, + 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x19, 0x0a, 0x15, 0x4d, 0x45, 0x53, 0x53, 0x41, + 0x47, 0x45, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x45, 0x5f, 0x50, 0x45, 0x4e, 0x44, 0x49, 0x4e, 0x47, + 0x10, 0x01, 0x12, 0x18, 0x0a, 0x14, 0x4d, 0x45, 0x53, 0x53, 0x41, 0x47, 0x45, 0x5f, 0x53, 0x54, + 0x41, 0x54, 0x45, 0x5f, 0x41, 0x43, 0x54, 0x49, 0x56, 0x45, 0x10, 0x02, 0x12, 0x18, 0x0a, 0x14, + 0x4d, 0x45, 0x53, 0x53, 0x41, 0x47, 0x45, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x45, 0x5f, 0x46, 0x41, + 0x49, 0x4c, 0x45, 0x44, 0x10, 0x03, 0x2a, 0x6b, 0x0a, 0x0d, 0x57, 0x61, 0x69, 0x74, 0x69, 0x6e, + 0x67, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x12, 0x1e, 0x0a, 0x1a, 0x57, 0x41, 0x49, 0x54, 0x49, + 0x4e, 0x47, 0x5f, 0x46, 0x49, 0x4c, 0x54, 0x45, 0x52, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, + 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x1a, 0x0a, 0x16, 0x57, 0x41, 0x49, 0x54, 0x49, + 0x4e, 0x47, 0x5f, 0x46, 0x49, 0x4c, 0x54, 0x45, 0x52, 0x5f, 0x57, 0x41, 0x49, 0x54, 0x49, 0x4e, + 0x47, 0x10, 0x01, 0x12, 0x1e, 0x0a, 0x1a, 0x57, 0x41, 0x49, 0x54, 0x49, 0x4e, 0x47, 0x5f, 0x46, + 0x49, 0x4c, 0x54, 0x45, 0x52, 0x5f, 0x4e, 0x4f, 0x54, 0x5f, 0x57, 0x41, 0x49, 0x54, 0x49, 0x4e, + 0x47, 0x10, 0x02, 0x32, 0xc7, 0x02, 0x0a, 0x0e, 0x53, 0x65, 0x6e, 0x64, 0x46, 0x69, 0x6c, 0x53, + 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x4e, 0x0a, 0x07, 0x53, 0x65, 0x6e, 0x64, 0x46, 0x69, + 0x6c, 0x12, 0x1f, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x73, 0x65, 0x6e, 0x64, 0x66, 0x69, 0x6c, 0x64, + 0x2e, 0x70, 0x62, 0x2e, 0x53, 0x65, 0x6e, 0x64, 0x46, 0x69, 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x1a, 0x20, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x73, 0x65, 0x6e, 0x64, 0x66, 0x69, 0x6c, + 0x64, 0x2e, 0x70, 0x62, 0x2e, 0x53, 0x65, 0x6e, 0x64, 0x46, 0x69, 0x6c, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x42, 0x0a, 0x03, 0x54, 0x78, 0x6e, 0x12, 0x1b, 0x2e, + 0x61, 0x70, 0x69, 0x2e, 0x73, 0x65, 0x6e, 0x64, 0x66, 0x69, 0x6c, 0x64, 0x2e, 0x70, 0x62, 0x2e, + 0x54, 0x78, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1c, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x73, 0x65, 0x6e, 0x64, 0x66, 0x69, 0x6c, 0x64, 0x2e, 0x70, 0x62, 0x2e, 0x54, 0x78, 0x6e, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1c, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x73, 0x65, - 0x6e, 0x64, 0x66, 0x69, 0x6c, 0x64, 0x2e, 0x70, 0x62, 0x2e, 0x54, 0x78, 0x6e, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x42, 0x31, 0x5a, 0x2f, 0x67, 0x69, 0x74, 0x68, 0x75, - 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x74, 0x65, 0x78, 0x74, 0x69, 0x6c, 0x65, 0x69, 0x6f, 0x2f, - 0x74, 0x65, 0x78, 0x74, 0x69, 0x6c, 0x65, 0x2f, 0x76, 0x32, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x73, - 0x65, 0x6e, 0x64, 0x66, 0x69, 0x6c, 0x64, 0x2f, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x33, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x51, 0x0a, 0x08, 0x4c, 0x69, + 0x73, 0x74, 0x54, 0x78, 0x6e, 0x73, 0x12, 0x20, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x73, 0x65, 0x6e, + 0x64, 0x66, 0x69, 0x6c, 0x64, 0x2e, 0x70, 0x62, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x54, 0x78, 0x6e, + 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x21, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x73, + 0x65, 0x6e, 0x64, 0x66, 0x69, 0x6c, 0x64, 0x2e, 0x70, 0x62, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x54, + 0x78, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x4e, 0x0a, + 0x07, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x12, 0x1f, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x73, + 0x65, 0x6e, 0x64, 0x66, 0x69, 0x6c, 0x64, 0x2e, 0x70, 0x62, 0x2e, 0x53, 0x75, 0x6d, 0x6d, 0x61, + 0x72, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x20, 0x2e, 0x61, 0x70, 0x69, 0x2e, + 0x73, 0x65, 0x6e, 0x64, 0x66, 0x69, 0x6c, 0x64, 0x2e, 0x70, 0x62, 0x2e, 0x53, 0x75, 0x6d, 0x6d, + 0x61, 0x72, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x42, 0x31, 0x5a, + 0x2f, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x74, 0x65, 0x78, 0x74, + 0x69, 0x6c, 0x65, 0x69, 0x6f, 0x2f, 0x74, 0x65, 0x78, 0x74, 0x69, 0x6c, 0x65, 0x2f, 0x76, 0x32, + 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x73, 0x65, 0x6e, 0x64, 0x66, 0x69, 0x6c, 0x64, 0x2f, 0x70, 0x62, + 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -506,32 +1094,50 @@ func file_api_sendfild_pb_sendfil_proto_rawDescGZIP() []byte { return file_api_sendfild_pb_sendfil_proto_rawDescData } -var file_api_sendfild_pb_sendfil_proto_enumTypes = make([]protoimpl.EnumInfo, 1) -var file_api_sendfild_pb_sendfil_proto_msgTypes = make([]protoimpl.MessageInfo, 5) +var file_api_sendfild_pb_sendfil_proto_enumTypes = make([]protoimpl.EnumInfo, 2) +var file_api_sendfild_pb_sendfil_proto_msgTypes = make([]protoimpl.MessageInfo, 9) var file_api_sendfild_pb_sendfil_proto_goTypes = []interface{}{ (MessageState)(0), // 0: api.sendfild.pb.MessageState - (*Txn)(nil), // 1: api.sendfild.pb.Txn - (*SendFilRequest)(nil), // 2: api.sendfild.pb.SendFilRequest - (*SendFilResponse)(nil), // 3: api.sendfild.pb.SendFilResponse - (*TxnRequest)(nil), // 4: api.sendfild.pb.TxnRequest - (*TxnResponse)(nil), // 5: api.sendfild.pb.TxnResponse - (*timestamp.Timestamp)(nil), // 6: google.protobuf.Timestamp + (WaitingFilter)(0), // 1: api.sendfild.pb.WaitingFilter + (*Txn)(nil), // 2: api.sendfild.pb.Txn + (*SendFilRequest)(nil), // 3: api.sendfild.pb.SendFilRequest + (*SendFilResponse)(nil), // 4: api.sendfild.pb.SendFilResponse + (*TxnRequest)(nil), // 5: api.sendfild.pb.TxnRequest + (*TxnResponse)(nil), // 6: api.sendfild.pb.TxnResponse + (*ListTxnsRequest)(nil), // 7: api.sendfild.pb.ListTxnsRequest + (*ListTxnsResponse)(nil), // 8: api.sendfild.pb.ListTxnsResponse + (*SummaryRequest)(nil), // 9: api.sendfild.pb.SummaryRequest + (*SummaryResponse)(nil), // 10: api.sendfild.pb.SummaryResponse + (*timestamp.Timestamp)(nil), // 11: google.protobuf.Timestamp } var file_api_sendfild_pb_sendfil_proto_depIdxs = []int32{ - 0, // 0: api.sendfild.pb.Txn.message_state:type_name -> api.sendfild.pb.MessageState - 6, // 1: api.sendfild.pb.Txn.created_at:type_name -> google.protobuf.Timestamp - 6, // 2: api.sendfild.pb.Txn.updated_at:type_name -> google.protobuf.Timestamp - 1, // 3: api.sendfild.pb.SendFilResponse.txn:type_name -> api.sendfild.pb.Txn - 1, // 4: api.sendfild.pb.TxnResponse.txn:type_name -> api.sendfild.pb.Txn - 2, // 5: api.sendfild.pb.SendFilService.SendFil:input_type -> api.sendfild.pb.SendFilRequest - 4, // 6: api.sendfild.pb.SendFilService.Txn:input_type -> api.sendfild.pb.TxnRequest - 3, // 7: api.sendfild.pb.SendFilService.SendFil:output_type -> api.sendfild.pb.SendFilResponse - 5, // 8: api.sendfild.pb.SendFilService.Txn:output_type -> api.sendfild.pb.TxnResponse - 7, // [7:9] is the sub-list for method output_type - 5, // [5:7] is the sub-list for method input_type - 5, // [5:5] is the sub-list for extension type_name - 5, // [5:5] is the sub-list for extension extendee - 0, // [0:5] is the sub-list for field type_name + 0, // 0: api.sendfild.pb.Txn.message_state:type_name -> api.sendfild.pb.MessageState + 11, // 1: api.sendfild.pb.Txn.created_at:type_name -> google.protobuf.Timestamp + 11, // 2: api.sendfild.pb.Txn.updated_at:type_name -> google.protobuf.Timestamp + 2, // 3: api.sendfild.pb.SendFilResponse.txn:type_name -> api.sendfild.pb.Txn + 2, // 4: api.sendfild.pb.TxnResponse.txn:type_name -> api.sendfild.pb.Txn + 0, // 5: api.sendfild.pb.ListTxnsRequest.message_state_filter:type_name -> api.sendfild.pb.MessageState + 1, // 6: api.sendfild.pb.ListTxnsRequest.waiting_filter:type_name -> api.sendfild.pb.WaitingFilter + 11, // 7: api.sendfild.pb.ListTxnsRequest.created_before:type_name -> google.protobuf.Timestamp + 11, // 8: api.sendfild.pb.ListTxnsRequest.created_after:type_name -> google.protobuf.Timestamp + 11, // 9: api.sendfild.pb.ListTxnsRequest.updated_before:type_name -> google.protobuf.Timestamp + 11, // 10: api.sendfild.pb.ListTxnsRequest.updated_after:type_name -> google.protobuf.Timestamp + 2, // 11: api.sendfild.pb.ListTxnsResponse.txns:type_name -> api.sendfild.pb.Txn + 11, // 12: api.sendfild.pb.SummaryRequest.since:type_name -> google.protobuf.Timestamp + 11, // 13: api.sendfild.pb.SummaryRequest.before:type_name -> google.protobuf.Timestamp + 3, // 14: api.sendfild.pb.SendFilService.SendFil:input_type -> api.sendfild.pb.SendFilRequest + 5, // 15: api.sendfild.pb.SendFilService.Txn:input_type -> api.sendfild.pb.TxnRequest + 7, // 16: api.sendfild.pb.SendFilService.ListTxns:input_type -> api.sendfild.pb.ListTxnsRequest + 9, // 17: api.sendfild.pb.SendFilService.Summary:input_type -> api.sendfild.pb.SummaryRequest + 4, // 18: api.sendfild.pb.SendFilService.SendFil:output_type -> api.sendfild.pb.SendFilResponse + 6, // 19: api.sendfild.pb.SendFilService.Txn:output_type -> api.sendfild.pb.TxnResponse + 8, // 20: api.sendfild.pb.SendFilService.ListTxns:output_type -> api.sendfild.pb.ListTxnsResponse + 10, // 21: api.sendfild.pb.SendFilService.Summary:output_type -> api.sendfild.pb.SummaryResponse + 18, // [18:22] is the sub-list for method output_type + 14, // [14:18] is the sub-list for method input_type + 14, // [14:14] is the sub-list for extension type_name + 14, // [14:14] is the sub-list for extension extendee + 0, // [0:14] is the sub-list for field type_name } func init() { file_api_sendfild_pb_sendfil_proto_init() } @@ -600,14 +1206,62 @@ func file_api_sendfild_pb_sendfil_proto_init() { return nil } } + file_api_sendfild_pb_sendfil_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ListTxnsRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_api_sendfild_pb_sendfil_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ListTxnsResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_api_sendfild_pb_sendfil_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*SummaryRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_api_sendfild_pb_sendfil_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*SummaryResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } } type x struct{} out := protoimpl.TypeBuilder{ File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_api_sendfild_pb_sendfil_proto_rawDesc, - NumEnums: 1, - NumMessages: 5, + NumEnums: 2, + NumMessages: 9, NumExtensions: 0, NumServices: 1, }, @@ -636,6 +1290,8 @@ const _ = grpc.SupportPackageIsVersion6 type SendFilServiceClient interface { SendFil(ctx context.Context, in *SendFilRequest, opts ...grpc.CallOption) (*SendFilResponse, error) Txn(ctx context.Context, in *TxnRequest, opts ...grpc.CallOption) (*TxnResponse, error) + ListTxns(ctx context.Context, in *ListTxnsRequest, opts ...grpc.CallOption) (*ListTxnsResponse, error) + Summary(ctx context.Context, in *SummaryRequest, opts ...grpc.CallOption) (*SummaryResponse, error) } type sendFilServiceClient struct { @@ -664,10 +1320,30 @@ func (c *sendFilServiceClient) Txn(ctx context.Context, in *TxnRequest, opts ... return out, nil } +func (c *sendFilServiceClient) ListTxns(ctx context.Context, in *ListTxnsRequest, opts ...grpc.CallOption) (*ListTxnsResponse, error) { + out := new(ListTxnsResponse) + err := c.cc.Invoke(ctx, "/api.sendfild.pb.SendFilService/ListTxns", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *sendFilServiceClient) Summary(ctx context.Context, in *SummaryRequest, opts ...grpc.CallOption) (*SummaryResponse, error) { + out := new(SummaryResponse) + err := c.cc.Invoke(ctx, "/api.sendfild.pb.SendFilService/Summary", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + // SendFilServiceServer is the server API for SendFilService service. type SendFilServiceServer interface { SendFil(context.Context, *SendFilRequest) (*SendFilResponse, error) Txn(context.Context, *TxnRequest) (*TxnResponse, error) + ListTxns(context.Context, *ListTxnsRequest) (*ListTxnsResponse, error) + Summary(context.Context, *SummaryRequest) (*SummaryResponse, error) } // UnimplementedSendFilServiceServer can be embedded to have forward compatible implementations. @@ -680,6 +1356,12 @@ func (*UnimplementedSendFilServiceServer) SendFil(context.Context, *SendFilReque func (*UnimplementedSendFilServiceServer) Txn(context.Context, *TxnRequest) (*TxnResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method Txn not implemented") } +func (*UnimplementedSendFilServiceServer) ListTxns(context.Context, *ListTxnsRequest) (*ListTxnsResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method ListTxns not implemented") +} +func (*UnimplementedSendFilServiceServer) Summary(context.Context, *SummaryRequest) (*SummaryResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method Summary not implemented") +} func RegisterSendFilServiceServer(s *grpc.Server, srv SendFilServiceServer) { s.RegisterService(&_SendFilService_serviceDesc, srv) @@ -721,6 +1403,42 @@ func _SendFilService_Txn_Handler(srv interface{}, ctx context.Context, dec func( return interceptor(ctx, in, info, handler) } +func _SendFilService_ListTxns_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(ListTxnsRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(SendFilServiceServer).ListTxns(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/api.sendfild.pb.SendFilService/ListTxns", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(SendFilServiceServer).ListTxns(ctx, req.(*ListTxnsRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _SendFilService_Summary_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(SummaryRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(SendFilServiceServer).Summary(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/api.sendfild.pb.SendFilService/Summary", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(SendFilServiceServer).Summary(ctx, req.(*SummaryRequest)) + } + return interceptor(ctx, in, info, handler) +} + var _SendFilService_serviceDesc = grpc.ServiceDesc{ ServiceName: "api.sendfild.pb.SendFilService", HandlerType: (*SendFilServiceServer)(nil), @@ -733,6 +1451,14 @@ var _SendFilService_serviceDesc = grpc.ServiceDesc{ MethodName: "Txn", Handler: _SendFilService_Txn_Handler, }, + { + MethodName: "ListTxns", + Handler: _SendFilService_ListTxns_Handler, + }, + { + MethodName: "Summary", + Handler: _SendFilService_Summary_Handler, + }, }, Streams: []grpc.StreamDesc{}, Metadata: "api/sendfild/pb/sendfil.proto", diff --git a/api/sendfild/pb/sendfil.proto b/api/sendfild/pb/sendfil.proto index eb708807f..eb70bcd08 100644 --- a/api/sendfild/pb/sendfil.proto +++ b/api/sendfild/pb/sendfil.proto @@ -11,11 +11,17 @@ enum MessageState { MESSAGE_STATE_FAILED = 3; } +enum WaitingFilter { + WAITING_FILTER_UNSPECIFIED = 0; + WAITING_FILTER_WAITING = 1; + WAITING_FILTER_NOT_WAITING = 2; +} + message Txn { string id = 1; string from = 2; string to = 3; - string amount = 4; + int64 amount_nano_fil = 4; string message_cid = 5; MessageState message_state = 6; bool waiting = 7; @@ -27,7 +33,7 @@ message Txn { message SendFilRequest { string from = 1; string to = 2; - string amount = 3; + int64 amount_nano_fil = 3; bool wait = 4; } @@ -44,7 +50,54 @@ message TxnResponse { Txn txn = 1; } +message ListTxnsRequest { + string from_filter = 1; + string to_filter = 2; + string involving_filter = 3; + int64 amount_nano_fil_lt_filter = 4; + int64 amount_nano_fil_gt_filter = 5; + int64 amount_nano_fil_lteq_filter = 6; + int64 amount_nano_fil_gteq_filter = 7; + int64 amount_nano_fil_eq_filter = 8; + MessageState message_state_filter = 9; + WaitingFilter waiting_filter = 10; + google.protobuf.Timestamp created_before = 11; + google.protobuf.Timestamp created_after = 12; + google.protobuf.Timestamp updated_before = 13; + google.protobuf.Timestamp updated_after = 14; + bool ascending = 15; + int64 more_token = 16; + int64 limit = 17; +} + +message ListTxnsResponse { + repeated Txn txns = 1; + bool more = 2; + int64 more_token = 3; +} + +message SummaryRequest { + google.protobuf.Timestamp since = 1; + google.protobuf.Timestamp before = 2; +} + +message SummaryResponse { + int64 count_txns = 1; + int64 count_pending = 2; + int64 count_active = 3; + int64 count_failed = 4; + int64 count_waiting = 5; + int64 count_from_addrs = 6; + int64 count_to_addrs = 7; + int64 total_nano_fil_sent = 8; + float avg_nano_fil_sent = 9; + int64 max_nano_fil_sent = 10; + int64 min_nano_fil_sent = 11; +} + service SendFilService { rpc SendFil(SendFilRequest) returns (SendFilResponse) {} rpc Txn(TxnRequest) returns (TxnResponse) {} + rpc ListTxns(ListTxnsRequest) returns (ListTxnsResponse) {} + rpc Summary(SummaryRequest) returns (SummaryResponse) {} } \ No newline at end of file diff --git a/api/sendfild/service/service.go b/api/sendfild/service/service.go index 66fc44200..803453d13 100644 --- a/api/sendfild/service/service.go +++ b/api/sendfild/service/service.go @@ -40,16 +40,16 @@ type msgCid struct { } type txn struct { - ID primitive.ObjectID `bson:"_id"` - From string `bson:"from"` - To string `bson:"to"` - Amount string `bson:"amount"` - MessageCids []msgCid `bson:"message_cids"` - MessageState pb.MessageState `bson:"message_state"` - Waiting bool `bson:"waiting"` - FailureMsg string `bson:"failure_msg"` - CreatedAt time.Time `bson:"created_at"` - UpdatedAt time.Time `bson:"updated_at"` + ID primitive.ObjectID `bson:"_id"` + From string `bson:"from"` + To string `bson:"to"` + AmountNanoFil int64 `bson:"amount_nano_fil"` + MessageCids []msgCid `bson:"message_cids"` + MessageState pb.MessageState `bson:"message_state"` + Waiting bool `bson:"waiting"` + FailureMsg string `bson:"failure_msg"` + CreatedAt time.Time `bson:"created_at"` + UpdatedAt time.Time `bson:"updated_at"` } func (t txn) latestMsgCid() (msgCid, error) { @@ -98,7 +98,7 @@ func New(ctx context.Context, config Config) (*Service, error) { Keys: bson.D{primitive.E{Key: "to", Value: 1}}, }, { - Keys: bson.D{primitive.E{Key: "amount", Value: 1}}, + Keys: bson.D{primitive.E{Key: "amount_nano_fil", Value: 1}}, }, // MongoDB automatically creates a multikey index if any indexed field is an array; // you do not need to explicitly specify the multikey type. @@ -150,10 +150,7 @@ func (s *Service) SendFil(ctx context.Context, req *pb.SendFilRequest) (*pb.Send return nil, status.Errorf(codes.InvalidArgument, "parsing to address: %v", err) } amount := &big.Int{} - _, ok := amount.SetString(req.Amount, 10) - if !ok { - return nil, status.Error(codes.InvalidArgument, "parsing amount") - } + _ = amount.SetInt64(req.AmountNanoFil) msg := &types.Message{ From: f, To: t, @@ -173,14 +170,14 @@ func (s *Service) SendFil(ctx context.Context, req *pb.SendFilRequest) (*pb.Send now := time.Now() tx := txn{ - ID: primitive.NewObjectID(), - From: req.From, - To: req.To, - Amount: req.Amount, - MessageCids: []msgCid{{Cid: sm.Message.Cid().String(), CreatedAt: now}}, - MessageState: pb.MessageState_MESSAGE_STATE_PENDING, - CreatedAt: now, - UpdatedAt: now, + ID: primitive.NewObjectID(), + From: req.From, + To: req.To, + AmountNanoFil: req.AmountNanoFil, + MessageCids: []msgCid{{Cid: sm.Message.Cid().String(), CreatedAt: now}}, + MessageState: pb.MessageState_MESSAGE_STATE_PENDING, + CreatedAt: now, + UpdatedAt: now, } if _, err = s.col.InsertOne(ctx, &tx); err != nil { @@ -235,6 +232,235 @@ func (s *Service) Txn(ctx context.Context, req *pb.TxnRequest) (*pb.TxnResponse, return &pb.TxnResponse{Txn: pbTx}, nil } +func (s *Service) ListTxns(ctx context.Context, req *pb.ListTxnsRequest) (*pb.ListTxnsResponse, error) { + findOpts := options.Find() + if req.Limit > 0 { + findOpts.Limit = &req.Limit + } + sort := -1 + if req.Ascending { + sort = 1 + } + findOpts.Sort = bson.D{primitive.E{Key: "created_at", Value: sort}} + filter := bson.M{} + + // Involving/from/to + if req.InvolvingFilter != "" { + filter["$or"] = bson.A{bson.M{"from": req.InvolvingFilter}, bson.M{"to": req.InvolvingFilter}} + } else { + if req.FromFilter != "" { + filter["from"] = req.FromFilter + } + if req.ToFilter != "" { + filter["to"] = req.ToFilter + } + } + + // Amount eq/gte/lts/gt/lt + if req.AmountNanoFilEqFilter != 0 { + filter["amount_nano_fil"] = req.AmountNanoFilEqFilter + } else { + if req.AmountNanoFilGteqFilter != 0 { + filter["amount_nano_fil"] = bson.M{"$gte": req.AmountNanoFilGteqFilter} + } else if req.AmountNanoFilGtFilter != 0 { + filter["amount_nano_fil"] = bson.M{"$gt": req.AmountNanoFilGtFilter} + } + + if req.AmountNanoFilLteqFilter != 0 { + filter["amount_nano_fil"] = bson.M{"$lte": req.AmountNanoFilLteqFilter} + } else if req.AmountNanoFilLtFilter != 0 { + filter["amount_nano_fil"] = bson.M{"$lt": req.AmountNanoFilLtFilter} + } + } + + // MessageState + if req.MessageStateFilter != pb.MessageState_MESSAGE_STATE_UNSPECIFIED { + filter["message_state"] = req.MessageStateFilter + } + + // Waiting + if req.WaitingFilter != pb.WaitingFilter_WAITING_FILTER_UNSPECIFIED { + filter["waiting"] = req.WaitingFilter == pb.WaitingFilter_WAITING_FILTER_WAITING + } + + // Updated after/before + if req.UpdatedAfter != nil { + filter["updated_at"] = bson.M{"$gt": req.UpdatedAfter.AsTime()} + } + if req.UpdatedBefore != nil { + filter["updated_at"] = bson.M{"$lt": req.UpdatedBefore.AsTime()} + } + + // Created after/before + if req.CreatedAfter != nil { + filter["created_at"] = bson.M{"$gt": req.CreatedAfter.AsTime()} + } + if req.CreatedBefore != nil { + filter["created_at"] = bson.M{"$lt": req.CreatedBefore.AsTime()} + } + + // Apply paging info + comp := "$lt" + if req.MoreToken != 0 { + if req.Ascending { + comp = "$gt" + } + t := time.Unix(0, req.MoreToken) + filter["created_at"] = bson.M{comp: &t} + } + + cursor, err := s.col.Find(ctx, filter, findOpts) + if err != nil { + return nil, status.Errorf(codes.Internal, "querying txns: %v", err) + } + defer cursor.Close(ctx) + var txns []txn + err = cursor.All(ctx, &txns) + if err != nil { + return nil, status.Errorf(codes.Internal, "decoding txns query results: %v", err) + } + + more := false + var startAt *time.Time + if len(txns) > 0 { + lastCreatedAt := &txns[len(txns)-1].CreatedAt + filter["created_at"] = bson.M{comp: *lastCreatedAt} + res := s.col.FindOne(ctx, filter) + if res.Err() != nil && res.Err() != mongo.ErrNoDocuments { + return nil, status.Errorf(codes.Internal, "checking for more data: %v", err) + } + if res.Err() != mongo.ErrNoDocuments { + more = true + startAt = lastCreatedAt + } + } + var pbTxns []*pb.Txn + for _, rec := range txns { + pbTxn, err := toPbTxn(rec) + if err != nil { + return nil, status.Errorf(codes.Internal, "converting txn to pb: %v", err) + } + pbTxns = append(pbTxns, pbTxn) + } + res := &pb.ListTxnsResponse{ + Txns: pbTxns, + More: more, + } + if startAt != nil { + res.MoreToken = startAt.UnixNano() + } + return res, nil +} + +func (s *Service) Summary(ctx context.Context, req *pb.SummaryRequest) (*pb.SummaryResponse, error) { + type entityCount struct { + ID interface{} `bson:"_id"` + Count int64 `bson:"count"` + } + type stats struct { + ID string `bson:"_id"` + Total int64 `bson:"total"` + Avg float32 `bson:"avg"` + Min int64 `bson:"min"` + Max int64 `bson:"max"` + } + type report struct { + All []entityCount `bson:"all"` + ByMessageState []entityCount `bson:"by_message_state"` + Waiting []entityCount `bson:"waiting"` + UniqueFrom []entityCount `bson:"unique_from"` + UniqueTo []entityCount `bson:"unique_to"` + SentFilStats []stats `bson:"sent_fil_stats"` + } + + createdAtMatch := bson.M{} + if req.Before != nil { + createdAtMatch["$lt"] = req.Before.AsTime() + } + if req.Since != nil { + createdAtMatch["$gt"] = req.Since.AsTime() + } + match := bson.M{} + if len(createdAtMatch) > 0 { + match["created_at"] = createdAtMatch + } + cursor, err := s.col.Aggregate(ctx, bson.A{ + bson.M{"$match": match}, + bson.M{"$facet": bson.M{ + "all": bson.A{ + bson.M{"$group": bson.M{"_id": nil, "count": bson.M{"$sum": 1}}}, + }, + "by_message_state": bson.A{ + bson.M{"$group": bson.M{"_id": "$message_state", "count": bson.M{"$sum": 1}}}, + }, + "waiting": bson.A{ + bson.M{"$match": bson.M{"waiting": true}}, + bson.M{"$group": bson.M{"_id": nil, "count": bson.M{"$sum": 1}}}, + }, + "unique_from": bson.A{ + bson.M{"$group": bson.M{"_id": "$from", "count": bson.M{"$sum": 1}}}, + }, + "unique_to": bson.A{ + bson.M{"$group": bson.M{"_id": "$to", "count": bson.M{"$sum": 1}}}, + }, + "sent_fil_stats": bson.A{ + bson.M{"$group": bson.M{ + "_id": nil, + "total": bson.M{"$sum": "$amount_nano_fil"}, + "avg": bson.M{"$avg": "$amount_nano_fil"}, + "max": bson.M{"$max": "$amount_nano_fil"}, + "min": bson.M{"$min": "$amount_nano_fil"}, + }}, + }, + }}, + }) + if err != nil { + return nil, status.Errorf(codes.Internal, "calling aggregate: %v", err) + } + var res []report + if err = cursor.All(ctx, &res); err != nil { + return nil, status.Errorf(codes.Internal, "decoding cursor results: %v", err) + } + if len(res) != 1 { + return nil, status.Errorf(codes.Internal, "unexpected number of aggregate results: %v", len(res)) + } + + r := res[0] + + resp := &pb.SummaryResponse{} + + if len(r.All) == 1 { + resp.CountTxns = r.All[0].Count + } + + for _, state := range r.ByMessageState { + switch pb.MessageState(state.ID.(int32)) { + case pb.MessageState_MESSAGE_STATE_PENDING: + resp.CountPending = state.Count + case pb.MessageState_MESSAGE_STATE_ACTIVE: + resp.CountActive = state.Count + case pb.MessageState_MESSAGE_STATE_FAILED: + resp.CountFailed = state.Count + } + } + + if len(r.Waiting) == 1 { + resp.CountWaiting = r.Waiting[0].Count + } + + resp.CountFromAddrs = int64(len(r.UniqueFrom)) + resp.CountToAddrs = int64(len(r.UniqueTo)) + + if len(r.SentFilStats) == 1 { + resp.TotalNanoFilSent = r.SentFilStats[0].Total + resp.AvgNanoFilSent = r.SentFilStats[0].Avg + resp.MaxNanoFilSent = r.SentFilStats[0].Max + resp.MinNanoFilSent = r.SentFilStats[0].Min + } + + return resp, nil +} + type waitResult struct { txn txn err error @@ -401,15 +627,15 @@ func toPbTxn(txn txn) (*pb.Txn, error) { return nil, err } return &pb.Txn{ - Id: txn.ID.Hex(), - From: txn.From, - To: txn.To, - Amount: txn.Amount, - MessageCid: latestMsgCid.Cid, - MessageState: txn.MessageState, - Waiting: txn.Waiting, - FailureMsg: txn.FailureMsg, - CreatedAt: timestamppb.New(txn.CreatedAt), - UpdatedAt: timestamppb.New(txn.UpdatedAt), + Id: txn.ID.Hex(), + From: txn.From, + To: txn.To, + AmountNanoFil: txn.AmountNanoFil, + MessageCid: latestMsgCid.Cid, + MessageState: txn.MessageState, + Waiting: txn.Waiting, + FailureMsg: txn.FailureMsg, + CreatedAt: timestamppb.New(txn.CreatedAt), + UpdatedAt: timestamppb.New(txn.UpdatedAt), }, nil } diff --git a/api/sendfild/service/service_test.go b/api/sendfild/service/service_test.go index a4fdf8d4b..6b5f6c994 100644 --- a/api/sendfild/service/service_test.go +++ b/api/sendfild/service/service_test.go @@ -44,7 +44,7 @@ func TestIt(t *testing.T) { c, lc, dAddr, cleanup := requireSetup(t, ctx) defer cleanup() addr := requireLotusAddress(t, ctx, lc) - res, err := c.SendFil(ctx, &pb.SendFilRequest{From: dAddr.String(), To: addr.String(), Amount: "1000", Wait: false}) + res, err := c.SendFil(ctx, &pb.SendFilRequest{From: dAddr.String(), To: addr.String(), AmountNanoFil: 1000, Wait: false}) require.NoError(t, err) require.NotEmpty(t, res.Txn.MessageCid) infoRes, err := c.Txn(ctx, &pb.TxnRequest{MessageCid: res.Txn.MessageCid, Wait: false}) @@ -58,6 +58,22 @@ func TestIt(t *testing.T) { require.NotNil(t, infoRes3) } +func TestSummary(t *testing.T) { + c, lc, dAddr, cleanup := requireSetup(t, ctx) + defer cleanup() + addr := requireLotusAddress(t, ctx, lc) + addr2 := requireLotusAddress(t, ctx, lc) + _, err := c.SendFil(ctx, &pb.SendFilRequest{From: dAddr.String(), To: addr.String(), AmountNanoFil: 2500, Wait: false}) + require.NoError(t, err) + _, err = c.SendFil(ctx, &pb.SendFilRequest{From: dAddr.String(), To: addr2.String(), AmountNanoFil: 1000, Wait: false}) + require.NoError(t, err) + _, err = c.SendFil(ctx, &pb.SendFilRequest{From: dAddr.String(), To: addr.String(), AmountNanoFil: 400, Wait: true}) + require.NoError(t, err) + summary, err := c.Summary(ctx, &pb.SummaryRequest{}) + require.NoError(t, err) + require.NotNil(t, summary) +} + func requireSetup(t *testing.T, ctx context.Context) (pb.SendFilServiceClient, *apistruct.FullNodeStruct, address.Address, func()) { clientBuilder, addr, _ := tests.CreateLocalDevnet(t, 1) time.Sleep(time.Millisecond * 500) // Allow the network to some tipsets From 3c893d880aa38b3f66b4c0649fb523052ae59852 Mon Sep 17 00:00:00 2001 From: Aaron Sutula Date: Tue, 2 Mar 2021 15:14:21 -0600 Subject: [PATCH 03/16] full tests and some bug fixes found along the way Signed-off-by: Aaron Sutula --- api/sendfild/pb/sendfil.pb.go | 20 +- api/sendfild/pb/sendfil.proto | 4 +- api/sendfild/service/service.go | 58 ++-- api/sendfild/service/service_test.go | 476 +++++++++++++++++++++++++-- go.mod | 18 +- go.sum | 106 ++++-- 6 files changed, 580 insertions(+), 102 deletions(-) diff --git a/api/sendfild/pb/sendfil.pb.go b/api/sendfild/pb/sendfil.pb.go index 43af195be..73c2e40f9 100644 --- a/api/sendfild/pb/sendfil.pb.go +++ b/api/sendfild/pb/sendfil.pb.go @@ -713,7 +713,7 @@ type SummaryRequest struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Since *timestamp.Timestamp `protobuf:"bytes,1,opt,name=since,proto3" json:"since,omitempty"` + After *timestamp.Timestamp `protobuf:"bytes,1,opt,name=after,proto3" json:"after,omitempty"` Before *timestamp.Timestamp `protobuf:"bytes,2,opt,name=before,proto3" json:"before,omitempty"` } @@ -749,9 +749,9 @@ func (*SummaryRequest) Descriptor() ([]byte, []int) { return file_api_sendfild_pb_sendfil_proto_rawDescGZIP(), []int{7} } -func (x *SummaryRequest) GetSince() *timestamp.Timestamp { +func (x *SummaryRequest) GetAfter() *timestamp.Timestamp { if x != nil { - return x.Since + return x.After } return nil } @@ -776,7 +776,7 @@ type SummaryResponse struct { CountFromAddrs int64 `protobuf:"varint,6,opt,name=count_from_addrs,json=countFromAddrs,proto3" json:"count_from_addrs,omitempty"` CountToAddrs int64 `protobuf:"varint,7,opt,name=count_to_addrs,json=countToAddrs,proto3" json:"count_to_addrs,omitempty"` TotalNanoFilSent int64 `protobuf:"varint,8,opt,name=total_nano_fil_sent,json=totalNanoFilSent,proto3" json:"total_nano_fil_sent,omitempty"` - AvgNanoFilSent float32 `protobuf:"fixed32,9,opt,name=avg_nano_fil_sent,json=avgNanoFilSent,proto3" json:"avg_nano_fil_sent,omitempty"` + AvgNanoFilSent float64 `protobuf:"fixed64,9,opt,name=avg_nano_fil_sent,json=avgNanoFilSent,proto3" json:"avg_nano_fil_sent,omitempty"` MaxNanoFilSent int64 `protobuf:"varint,10,opt,name=max_nano_fil_sent,json=maxNanoFilSent,proto3" json:"max_nano_fil_sent,omitempty"` MinNanoFilSent int64 `protobuf:"varint,11,opt,name=min_nano_fil_sent,json=minNanoFilSent,proto3" json:"min_nano_fil_sent,omitempty"` } @@ -869,7 +869,7 @@ func (x *SummaryResponse) GetTotalNanoFilSent() int64 { return 0 } -func (x *SummaryResponse) GetAvgNanoFilSent() float32 { +func (x *SummaryResponse) GetAvgNanoFilSent() float64 { if x != nil { return x.AvgNanoFilSent } @@ -1006,10 +1006,10 @@ var file_api_sendfild_pb_sendfil_proto_rawDesc = []byte{ 0x0a, 0x0a, 0x6d, 0x6f, 0x72, 0x65, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x6d, 0x6f, 0x72, 0x65, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0x76, 0x0a, 0x0e, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, - 0x30, 0x0a, 0x05, 0x73, 0x69, 0x6e, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, + 0x30, 0x0a, 0x05, 0x61, 0x66, 0x74, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, - 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x05, 0x73, 0x69, 0x6e, 0x63, - 0x65, 0x12, 0x32, 0x0a, 0x06, 0x62, 0x65, 0x66, 0x6f, 0x72, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x05, 0x61, 0x66, 0x74, 0x65, + 0x72, 0x12, 0x32, 0x0a, 0x06, 0x62, 0x65, 0x66, 0x6f, 0x72, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x06, 0x62, 0x65, 0x66, 0x6f, 0x72, 0x65, 0x22, 0xc0, 0x03, 0x0a, 0x0f, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, @@ -1034,7 +1034,7 @@ var file_api_sendfild_pb_sendfil_proto_rawDesc = []byte{ 0x08, 0x20, 0x01, 0x28, 0x03, 0x52, 0x10, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x4e, 0x61, 0x6e, 0x6f, 0x46, 0x69, 0x6c, 0x53, 0x65, 0x6e, 0x74, 0x12, 0x29, 0x0a, 0x11, 0x61, 0x76, 0x67, 0x5f, 0x6e, 0x61, 0x6e, 0x6f, 0x5f, 0x66, 0x69, 0x6c, 0x5f, 0x73, 0x65, 0x6e, 0x74, 0x18, 0x09, 0x20, 0x01, - 0x28, 0x02, 0x52, 0x0e, 0x61, 0x76, 0x67, 0x4e, 0x61, 0x6e, 0x6f, 0x46, 0x69, 0x6c, 0x53, 0x65, + 0x28, 0x01, 0x52, 0x0e, 0x61, 0x76, 0x67, 0x4e, 0x61, 0x6e, 0x6f, 0x46, 0x69, 0x6c, 0x53, 0x65, 0x6e, 0x74, 0x12, 0x29, 0x0a, 0x11, 0x6d, 0x61, 0x78, 0x5f, 0x6e, 0x61, 0x6e, 0x6f, 0x5f, 0x66, 0x69, 0x6c, 0x5f, 0x73, 0x65, 0x6e, 0x74, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0e, 0x6d, 0x61, 0x78, 0x4e, 0x61, 0x6e, 0x6f, 0x46, 0x69, 0x6c, 0x53, 0x65, 0x6e, 0x74, 0x12, 0x29, 0x0a, @@ -1123,7 +1123,7 @@ var file_api_sendfild_pb_sendfil_proto_depIdxs = []int32{ 11, // 9: api.sendfild.pb.ListTxnsRequest.updated_before:type_name -> google.protobuf.Timestamp 11, // 10: api.sendfild.pb.ListTxnsRequest.updated_after:type_name -> google.protobuf.Timestamp 2, // 11: api.sendfild.pb.ListTxnsResponse.txns:type_name -> api.sendfild.pb.Txn - 11, // 12: api.sendfild.pb.SummaryRequest.since:type_name -> google.protobuf.Timestamp + 11, // 12: api.sendfild.pb.SummaryRequest.after:type_name -> google.protobuf.Timestamp 11, // 13: api.sendfild.pb.SummaryRequest.before:type_name -> google.protobuf.Timestamp 3, // 14: api.sendfild.pb.SendFilService.SendFil:input_type -> api.sendfild.pb.SendFilRequest 5, // 15: api.sendfild.pb.SendFilService.Txn:input_type -> api.sendfild.pb.TxnRequest diff --git a/api/sendfild/pb/sendfil.proto b/api/sendfild/pb/sendfil.proto index eb70bcd08..aace918f1 100644 --- a/api/sendfild/pb/sendfil.proto +++ b/api/sendfild/pb/sendfil.proto @@ -77,7 +77,7 @@ message ListTxnsResponse { } message SummaryRequest { - google.protobuf.Timestamp since = 1; + google.protobuf.Timestamp after = 1; google.protobuf.Timestamp before = 2; } @@ -90,7 +90,7 @@ message SummaryResponse { int64 count_from_addrs = 6; int64 count_to_addrs = 7; int64 total_nano_fil_sent = 8; - float avg_nano_fil_sent = 9; + double avg_nano_fil_sent = 9; int64 max_nano_fil_sent = 10; int64 min_nano_fil_sent = 11; } diff --git a/api/sendfild/service/service.go b/api/sendfild/service/service.go index 803453d13..8bbdad679 100644 --- a/api/sendfild/service/service.go +++ b/api/sendfild/service/service.go @@ -4,6 +4,7 @@ import ( "context" "errors" "fmt" + "math" "math/big" "net" "sync" @@ -149,8 +150,9 @@ func (s *Service) SendFil(ctx context.Context, req *pb.SendFilRequest) (*pb.Send if err != nil { return nil, status.Errorf(codes.InvalidArgument, "parsing to address: %v", err) } - amount := &big.Int{} - _ = amount.SetInt64(req.AmountNanoFil) + nanoAmount := (&big.Int{}).SetInt64(req.AmountNanoFil) + factor := (&big.Int{}).SetInt64(int64(math.Pow10(9))) + amount := (&big.Int{}).Mul(nanoAmount, factor) msg := &types.Message{ From: f, To: t, @@ -205,7 +207,7 @@ func (s *Service) SendFil(ctx context.Context, req *pb.SendFilRequest) (*pb.Send func (s *Service) Txn(ctx context.Context, req *pb.TxnRequest) (*pb.TxnResponse, error) { res := s.col.FindOne(ctx, bson.M{"message_cids.cid": req.MessageCid}) if res.Err() == mongo.ErrNoDocuments { - return nil, status.Error(codes.InvalidArgument, "no txn found for cid") + return nil, status.Error(codes.NotFound, "no txn found for cid") } if res.Err() != nil { return nil, status.Errorf(codes.Internal, "querying for cid txn: %v", res.Err()) @@ -256,47 +258,49 @@ func (s *Service) ListTxns(ctx context.Context, req *pb.ListTxnsRequest) (*pb.Li } } + // MessageState + if req.MessageStateFilter != pb.MessageState_MESSAGE_STATE_UNSPECIFIED { + filter["message_state"] = req.MessageStateFilter + } + + // Waiting + if req.WaitingFilter != pb.WaitingFilter_WAITING_FILTER_UNSPECIFIED { + filter["waiting"] = req.WaitingFilter == pb.WaitingFilter_WAITING_FILTER_WAITING + } + + ands := bson.A{} + // Amount eq/gte/lts/gt/lt if req.AmountNanoFilEqFilter != 0 { filter["amount_nano_fil"] = req.AmountNanoFilEqFilter } else { if req.AmountNanoFilGteqFilter != 0 { - filter["amount_nano_fil"] = bson.M{"$gte": req.AmountNanoFilGteqFilter} + ands = append(ands, bson.M{"amount_nano_fil": bson.M{"$gte": req.AmountNanoFilGteqFilter}}) } else if req.AmountNanoFilGtFilter != 0 { - filter["amount_nano_fil"] = bson.M{"$gt": req.AmountNanoFilGtFilter} + ands = append(ands, bson.M{"amount_nano_fil": bson.M{"$gt": req.AmountNanoFilGtFilter}}) } if req.AmountNanoFilLteqFilter != 0 { - filter["amount_nano_fil"] = bson.M{"$lte": req.AmountNanoFilLteqFilter} + ands = append(ands, bson.M{"amount_nano_fil": bson.M{"$lte": req.AmountNanoFilLteqFilter}}) } else if req.AmountNanoFilLtFilter != 0 { - filter["amount_nano_fil"] = bson.M{"$lt": req.AmountNanoFilLtFilter} + ands = append(ands, bson.M{"amount_nano_fil": bson.M{"$lt": req.AmountNanoFilLtFilter}}) } } - // MessageState - if req.MessageStateFilter != pb.MessageState_MESSAGE_STATE_UNSPECIFIED { - filter["message_state"] = req.MessageStateFilter - } - - // Waiting - if req.WaitingFilter != pb.WaitingFilter_WAITING_FILTER_UNSPECIFIED { - filter["waiting"] = req.WaitingFilter == pb.WaitingFilter_WAITING_FILTER_WAITING - } - // Updated after/before if req.UpdatedAfter != nil { - filter["updated_at"] = bson.M{"$gt": req.UpdatedAfter.AsTime()} + ands = append(ands, bson.M{"updated_at": bson.M{"$gt": req.UpdatedAfter.AsTime()}}) } if req.UpdatedBefore != nil { - filter["updated_at"] = bson.M{"$lt": req.UpdatedBefore.AsTime()} + ands = append(ands, bson.M{"updated_at": bson.M{"$lt": req.UpdatedBefore.AsTime()}}) } // Created after/before if req.CreatedAfter != nil { - filter["created_at"] = bson.M{"$gt": req.CreatedAfter.AsTime()} + ands = append(ands, bson.M{"created_at": bson.M{"$gt": req.CreatedAfter.AsTime()}}) } if req.CreatedBefore != nil { - filter["created_at"] = bson.M{"$lt": req.CreatedBefore.AsTime()} + ands = append(ands, bson.M{"created_at": bson.M{"$lt": req.CreatedBefore.AsTime()}}) } // Apply paging info @@ -306,7 +310,11 @@ func (s *Service) ListTxns(ctx context.Context, req *pb.ListTxnsRequest) (*pb.Li comp = "$gt" } t := time.Unix(0, req.MoreToken) - filter["created_at"] = bson.M{comp: &t} + ands = append(ands, bson.M{"created_at": bson.M{comp: &t}}) + } + + if len(ands) > 0 { + filter["$and"] = ands } cursor, err := s.col.Find(ctx, filter, findOpts) @@ -360,7 +368,7 @@ func (s *Service) Summary(ctx context.Context, req *pb.SummaryRequest) (*pb.Summ type stats struct { ID string `bson:"_id"` Total int64 `bson:"total"` - Avg float32 `bson:"avg"` + Avg float64 `bson:"avg"` Min int64 `bson:"min"` Max int64 `bson:"max"` } @@ -377,8 +385,8 @@ func (s *Service) Summary(ctx context.Context, req *pb.SummaryRequest) (*pb.Summ if req.Before != nil { createdAtMatch["$lt"] = req.Before.AsTime() } - if req.Since != nil { - createdAtMatch["$gt"] = req.Since.AsTime() + if req.After != nil { + createdAtMatch["$gt"] = req.After.AsTime() } match := bson.M{} if len(createdAtMatch) > 0 { diff --git a/api/sendfild/service/service_test.go b/api/sendfild/service/service_test.go index 6b5f6c994..92894e504 100644 --- a/api/sendfild/service/service_test.go +++ b/api/sendfild/service/service_test.go @@ -2,6 +2,7 @@ package service import ( "context" + "math/rand" "net" "os" "testing" @@ -10,7 +11,9 @@ import ( "github.com/filecoin-project/go-address" "github.com/filecoin-project/lotus/api/apistruct" "github.com/filecoin-project/lotus/chain/types" + "github.com/ipfs/go-cid" logging "github.com/ipfs/go-log/v2" + mh "github.com/multiformats/go-multihash" "github.com/stretchr/testify/require" "github.com/textileio/go-ds-mongo/test" "github.com/textileio/powergate/v2/tests" @@ -18,10 +21,15 @@ import ( pb "github.com/textileio/textile/v2/api/sendfild/pb" "github.com/textileio/textile/v2/util" "google.golang.org/grpc" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" "google.golang.org/grpc/test/bufconn" ) -const bufSize = 1024 * 1024 +const ( + bufSize = 1024 * 1024 + oneFil = 1000000000 +) var ( ctx, _ = context.WithTimeout(context.Background(), 2*time.Minute) @@ -40,42 +48,434 @@ func TestMain(m *testing.M) { os.Exit(exitVal) } -func TestIt(t *testing.T) { - c, lc, dAddr, cleanup := requireSetup(t, ctx) +func TestSendFil(t *testing.T) { + c, lc, dAddr, cleanup := requireSetup(t, ctx, 300) + defer cleanup() + addr := requireLotusAddress(t, ctx, lc) + txn := requireSendFil(t, ctx, c, dAddr.String(), addr.String(), oneFil, false) + require.Equal(t, pb.MessageState_MESSAGE_STATE_PENDING, txn.MessageState) +} + +func TestSendFilWait(t *testing.T) { + c, lc, dAddr, cleanup := requireSetup(t, ctx, 300) + defer cleanup() + addr := requireLotusAddress(t, ctx, lc) + txn := requireSendFil(t, ctx, c, dAddr.String(), addr.String(), oneFil, true) + require.Equal(t, pb.MessageState_MESSAGE_STATE_ACTIVE, txn.MessageState) +} + +func TestTxn(t *testing.T) { + c, lc, dAddr, cleanup := requireSetup(t, ctx, 1000) defer cleanup() addr := requireLotusAddress(t, ctx, lc) - res, err := c.SendFil(ctx, &pb.SendFilRequest{From: dAddr.String(), To: addr.String(), AmountNanoFil: 1000, Wait: false}) + txn := requireSendFil(t, ctx, c, dAddr.String(), addr.String(), oneFil, false) + res, err := c.Txn(ctx, &pb.TxnRequest{MessageCid: txn.MessageCid, Wait: false}) require.NoError(t, err) - require.NotEmpty(t, res.Txn.MessageCid) - infoRes, err := c.Txn(ctx, &pb.TxnRequest{MessageCid: res.Txn.MessageCid, Wait: false}) + require.Equal(t, txn.MessageCid, res.Txn.MessageCid) + require.Equal(t, pb.MessageState_MESSAGE_STATE_PENDING, res.Txn.MessageState) +} + +func TestTxnWait(t *testing.T) { + c, lc, dAddr, cleanup := requireSetup(t, ctx, 300) + defer cleanup() + addr := requireLotusAddress(t, ctx, lc) + txn1 := requireSendFil(t, ctx, c, dAddr.String(), addr.String(), oneFil, false) + res, err := c.Txn(ctx, &pb.TxnRequest{MessageCid: txn1.MessageCid, Wait: true}) require.NoError(t, err) - require.NotNil(t, infoRes) - infoRes2, err := c.Txn(ctx, &pb.TxnRequest{MessageCid: res.Txn.MessageCid, Wait: true}) + require.Equal(t, txn1.MessageCid, res.Txn.MessageCid) + require.Equal(t, pb.MessageState_MESSAGE_STATE_ACTIVE, res.Txn.MessageState) +} + +func TestTxnNonExistent(t *testing.T) { + c, _, _, cleanup := requireSetup(t, ctx, 300) + defer cleanup() + _, err := c.Txn(ctx, &pb.TxnRequest{MessageCid: randomCid().String()}) + require.Equal(t, codes.NotFound, status.Code(err)) +} + +func TestListTxns(t *testing.T) { + c, lc, dAddr, cleanup := requireSetup(t, ctx, 300) + defer cleanup() + addr := requireLotusAddress(t, ctx, lc) + requireSendFil(t, ctx, c, dAddr.String(), addr.String(), oneFil, false) + requireSendFil(t, ctx, c, dAddr.String(), addr.String(), oneFil, false) + requireSendFil(t, ctx, c, dAddr.String(), addr.String(), oneFil, false) + res, err := c.ListTxns(ctx, &pb.ListTxnsRequest{}) + require.NoError(t, err) + require.Len(t, res.Txns, 3) +} + +func TestListTxnsFrom(t *testing.T) { + c, lc, dAddr, cleanup := requireSetup(t, ctx, 300) + defer cleanup() + addr1 := requireLotusAddress(t, ctx, lc) + addr2 := requireLotusAddress(t, ctx, lc) + requireSendFil(t, ctx, c, dAddr.String(), addr1.String(), oneFil, false) + requireSendFil(t, ctx, c, dAddr.String(), addr1.String(), oneFil, false) + requireSendFil(t, ctx, c, dAddr.String(), addr2.String(), oneFil*2, true) + requireSendFil(t, ctx, c, addr2.String(), addr1.String(), oneFil, false) + res, err := c.ListTxns(ctx, &pb.ListTxnsRequest{FromFilter: dAddr.String()}) require.NoError(t, err) - require.NotNil(t, infoRes2) - infoRes3, err := c.Txn(ctx, &pb.TxnRequest{MessageCid: res.Txn.MessageCid, Wait: true}) + require.Len(t, res.Txns, 3) + res, err = c.ListTxns(ctx, &pb.ListTxnsRequest{FromFilter: addr2.String()}) require.NoError(t, err) - require.NotNil(t, infoRes3) + require.Len(t, res.Txns, 1) } -func TestSummary(t *testing.T) { - c, lc, dAddr, cleanup := requireSetup(t, ctx) +func TestListTxnsTo(t *testing.T) { + c, lc, dAddr, cleanup := requireSetup(t, ctx, 300) defer cleanup() - addr := requireLotusAddress(t, ctx, lc) + addr1 := requireLotusAddress(t, ctx, lc) addr2 := requireLotusAddress(t, ctx, lc) - _, err := c.SendFil(ctx, &pb.SendFilRequest{From: dAddr.String(), To: addr.String(), AmountNanoFil: 2500, Wait: false}) + requireSendFil(t, ctx, c, dAddr.String(), addr1.String(), oneFil, false) + requireSendFil(t, ctx, c, dAddr.String(), addr1.String(), oneFil, false) + requireSendFil(t, ctx, c, dAddr.String(), addr2.String(), oneFil*2, true) + requireSendFil(t, ctx, c, addr2.String(), addr1.String(), oneFil, false) + res, err := c.ListTxns(ctx, &pb.ListTxnsRequest{ToFilter: addr1.String()}) + require.NoError(t, err) + require.Len(t, res.Txns, 3) + res, err = c.ListTxns(ctx, &pb.ListTxnsRequest{ToFilter: addr2.String()}) require.NoError(t, err) - _, err = c.SendFil(ctx, &pb.SendFilRequest{From: dAddr.String(), To: addr2.String(), AmountNanoFil: 1000, Wait: false}) + require.Len(t, res.Txns, 1) +} + +func TestListTxnsInvolving(t *testing.T) { + c, lc, dAddr, cleanup := requireSetup(t, ctx, 300) + defer cleanup() + addr1 := requireLotusAddress(t, ctx, lc) + addr2 := requireLotusAddress(t, ctx, lc) + requireSendFil(t, ctx, c, dAddr.String(), addr1.String(), oneFil, false) + requireSendFil(t, ctx, c, dAddr.String(), addr1.String(), oneFil, false) + requireSendFil(t, ctx, c, dAddr.String(), addr2.String(), oneFil*2, true) + requireSendFil(t, ctx, c, addr2.String(), addr1.String(), oneFil, false) + res, err := c.ListTxns(ctx, &pb.ListTxnsRequest{InvolvingFilter: dAddr.String()}) require.NoError(t, err) - _, err = c.SendFil(ctx, &pb.SendFilRequest{From: dAddr.String(), To: addr.String(), AmountNanoFil: 400, Wait: true}) + require.Len(t, res.Txns, 3) + res, err = c.ListTxns(ctx, &pb.ListTxnsRequest{InvolvingFilter: addr1.String()}) require.NoError(t, err) - summary, err := c.Summary(ctx, &pb.SummaryRequest{}) + require.Len(t, res.Txns, 3) + res, err = c.ListTxns(ctx, &pb.ListTxnsRequest{InvolvingFilter: addr2.String()}) + require.NoError(t, err) + require.Len(t, res.Txns, 2) +} + +func TestListTxnsAmtGt(t *testing.T) { + c, lc, dAddr, cleanup := requireSetup(t, ctx, 300) + defer cleanup() + addr1 := requireLotusAddress(t, ctx, lc) + requireSendFil(t, ctx, c, dAddr.String(), addr1.String(), oneFil/2, false) + requireSendFil(t, ctx, c, dAddr.String(), addr1.String(), oneFil, false) + requireSendFil(t, ctx, c, dAddr.String(), addr1.String(), oneFil*2, false) + res, err := c.ListTxns(ctx, &pb.ListTxnsRequest{AmountNanoFilGtFilter: oneFil}) + require.NoError(t, err) + require.Len(t, res.Txns, 1) + res, err = c.ListTxns(ctx, &pb.ListTxnsRequest{AmountNanoFilGtFilter: oneFil * 2}) + require.NoError(t, err) + require.Len(t, res.Txns, 0) +} + +func TestListTxnsAmtGteq(t *testing.T) { + c, lc, dAddr, cleanup := requireSetup(t, ctx, 300) + defer cleanup() + addr1 := requireLotusAddress(t, ctx, lc) + requireSendFil(t, ctx, c, dAddr.String(), addr1.String(), oneFil/2, false) + requireSendFil(t, ctx, c, dAddr.String(), addr1.String(), oneFil, false) + requireSendFil(t, ctx, c, dAddr.String(), addr1.String(), oneFil*2, false) + res, err := c.ListTxns(ctx, &pb.ListTxnsRequest{AmountNanoFilGteqFilter: oneFil}) + require.NoError(t, err) + require.Len(t, res.Txns, 2) + res, err = c.ListTxns(ctx, &pb.ListTxnsRequest{AmountNanoFilGteqFilter: oneFil * 3}) + require.NoError(t, err) + require.Len(t, res.Txns, 0) +} + +func TestListTxnsAmtLt(t *testing.T) { + c, lc, dAddr, cleanup := requireSetup(t, ctx, 300) + defer cleanup() + addr1 := requireLotusAddress(t, ctx, lc) + requireSendFil(t, ctx, c, dAddr.String(), addr1.String(), oneFil/2, false) + requireSendFil(t, ctx, c, dAddr.String(), addr1.String(), oneFil, false) + requireSendFil(t, ctx, c, dAddr.String(), addr1.String(), oneFil*2, false) + res, err := c.ListTxns(ctx, &pb.ListTxnsRequest{AmountNanoFilLtFilter: oneFil}) + require.NoError(t, err) + require.Len(t, res.Txns, 1) + res, err = c.ListTxns(ctx, &pb.ListTxnsRequest{AmountNanoFilLtFilter: oneFil / 2}) + require.NoError(t, err) + require.Len(t, res.Txns, 0) +} + +func TestListTxnsAmtLteq(t *testing.T) { + c, lc, dAddr, cleanup := requireSetup(t, ctx, 300) + defer cleanup() + addr1 := requireLotusAddress(t, ctx, lc) + requireSendFil(t, ctx, c, dAddr.String(), addr1.String(), oneFil/2, false) + requireSendFil(t, ctx, c, dAddr.String(), addr1.String(), oneFil, false) + requireSendFil(t, ctx, c, dAddr.String(), addr1.String(), oneFil*2, false) + res, err := c.ListTxns(ctx, &pb.ListTxnsRequest{AmountNanoFilLteqFilter: oneFil}) + require.NoError(t, err) + require.Len(t, res.Txns, 2) + res, err = c.ListTxns(ctx, &pb.ListTxnsRequest{AmountNanoFilLteqFilter: oneFil / 3}) + require.NoError(t, err) + require.Len(t, res.Txns, 0) +} + +func TestListTxnsAmtGtLt(t *testing.T) { + c, lc, dAddr, cleanup := requireSetup(t, ctx, 300) + defer cleanup() + addr1 := requireLotusAddress(t, ctx, lc) + requireSendFil(t, ctx, c, dAddr.String(), addr1.String(), oneFil/2, false) + requireSendFil(t, ctx, c, dAddr.String(), addr1.String(), oneFil, false) + requireSendFil(t, ctx, c, dAddr.String(), addr1.String(), oneFil*2, false) + res, err := c.ListTxns(ctx, &pb.ListTxnsRequest{AmountNanoFilGtFilter: oneFil / 2, AmountNanoFilLtFilter: oneFil * 3 / 2}) + require.NoError(t, err) + require.Len(t, res.Txns, 1) +} + +func TestListTxnsAmtGteqLteq(t *testing.T) { + c, lc, dAddr, cleanup := requireSetup(t, ctx, 300) + defer cleanup() + addr1 := requireLotusAddress(t, ctx, lc) + requireSendFil(t, ctx, c, dAddr.String(), addr1.String(), oneFil/2, false) + requireSendFil(t, ctx, c, dAddr.String(), addr1.String(), oneFil, false) + requireSendFil(t, ctx, c, dAddr.String(), addr1.String(), oneFil*2, false) + requireSendFil(t, ctx, c, dAddr.String(), addr1.String(), oneFil*3, false) + res, err := c.ListTxns(ctx, &pb.ListTxnsRequest{AmountNanoFilGteqFilter: oneFil, AmountNanoFilLteqFilter: oneFil * 2}) + require.NoError(t, err) + require.Len(t, res.Txns, 2) +} + +func TestListTxnsAmtGteqLt(t *testing.T) { + c, lc, dAddr, cleanup := requireSetup(t, ctx, 300) + defer cleanup() + addr1 := requireLotusAddress(t, ctx, lc) + requireSendFil(t, ctx, c, dAddr.String(), addr1.String(), oneFil/2, false) + requireSendFil(t, ctx, c, dAddr.String(), addr1.String(), oneFil, false) + requireSendFil(t, ctx, c, dAddr.String(), addr1.String(), oneFil*2, false) + res, err := c.ListTxns(ctx, &pb.ListTxnsRequest{AmountNanoFilGteqFilter: oneFil / 2, AmountNanoFilLtFilter: oneFil * 3 / 2}) require.NoError(t, err) - require.NotNil(t, summary) + require.Len(t, res.Txns, 2) } -func requireSetup(t *testing.T, ctx context.Context) (pb.SendFilServiceClient, *apistruct.FullNodeStruct, address.Address, func()) { - clientBuilder, addr, _ := tests.CreateLocalDevnet(t, 1) +func TestListTxnsAmtGtLteq(t *testing.T) { + c, lc, dAddr, cleanup := requireSetup(t, ctx, 300) + defer cleanup() + addr1 := requireLotusAddress(t, ctx, lc) + requireSendFil(t, ctx, c, dAddr.String(), addr1.String(), oneFil/2, false) + requireSendFil(t, ctx, c, dAddr.String(), addr1.String(), oneFil, false) + requireSendFil(t, ctx, c, dAddr.String(), addr1.String(), oneFil*2, false) + requireSendFil(t, ctx, c, dAddr.String(), addr1.String(), oneFil*3, false) + res, err := c.ListTxns(ctx, &pb.ListTxnsRequest{AmountNanoFilGtFilter: oneFil, AmountNanoFilLteqFilter: oneFil * 2}) + require.NoError(t, err) + require.Len(t, res.Txns, 1) +} + +func TestListTxnsMessageState(t *testing.T) { + c, lc, dAddr, cleanup := requireSetup(t, ctx, 1000) + defer cleanup() + addr1 := requireLotusAddress(t, ctx, lc) + requireSendFil(t, ctx, c, dAddr.String(), addr1.String(), oneFil, true) + requireSendFil(t, ctx, c, dAddr.String(), addr1.String(), oneFil, false) + requireSendFil(t, ctx, c, dAddr.String(), addr1.String(), oneFil, false) + res, err := c.ListTxns(ctx, &pb.ListTxnsRequest{MessageStateFilter: pb.MessageState_MESSAGE_STATE_ACTIVE}) + require.NoError(t, err) + require.Len(t, res.Txns, 1) + res, err = c.ListTxns(ctx, &pb.ListTxnsRequest{MessageStateFilter: pb.MessageState_MESSAGE_STATE_PENDING}) + require.NoError(t, err) + require.Len(t, res.Txns, 2) +} + +func TestListTxnsWaiting(t *testing.T) { + c, lc, dAddr, cleanup := requireSetup(t, ctx, 1000) + defer cleanup() + addr1 := requireLotusAddress(t, ctx, lc) + requireSendFil(t, ctx, c, dAddr.String(), addr1.String(), oneFil, true) + requireSendFil(t, ctx, c, dAddr.String(), addr1.String(), oneFil, false) + requireSendFil(t, ctx, c, dAddr.String(), addr1.String(), oneFil, false) + time.Sleep(time.Millisecond * 100) // Little time to allow the monitoring process to start waiting for all the txns. + res, err := c.ListTxns(ctx, &pb.ListTxnsRequest{WaitingFilter: pb.WaitingFilter_WAITING_FILTER_NOT_WAITING}) + require.NoError(t, err) + require.Len(t, res.Txns, 1) + res, err = c.ListTxns(ctx, &pb.ListTxnsRequest{WaitingFilter: pb.WaitingFilter_WAITING_FILTER_WAITING}) + require.NoError(t, err) + require.Len(t, res.Txns, 2) +} + +func TestListTxnsCreatedAfter(t *testing.T) { + c, lc, dAddr, cleanup := requireSetup(t, ctx, 300) + defer cleanup() + addr1 := requireLotusAddress(t, ctx, lc) + t1 := requireSendFil(t, ctx, c, dAddr.String(), addr1.String(), oneFil, false) + requireSendFil(t, ctx, c, dAddr.String(), addr1.String(), oneFil, false) + requireSendFil(t, ctx, c, dAddr.String(), addr1.String(), oneFil, false) + res, err := c.ListTxns(ctx, &pb.ListTxnsRequest{CreatedAfter: t1.CreatedAt}) + require.NoError(t, err) + require.Len(t, res.Txns, 2) +} + +func TestListTxnsCreatedBefore(t *testing.T) { + c, lc, dAddr, cleanup := requireSetup(t, ctx, 300) + defer cleanup() + addr1 := requireLotusAddress(t, ctx, lc) + requireSendFil(t, ctx, c, dAddr.String(), addr1.String(), oneFil, false) + requireSendFil(t, ctx, c, dAddr.String(), addr1.String(), oneFil, false) + t3 := requireSendFil(t, ctx, c, dAddr.String(), addr1.String(), oneFil, false) + res, err := c.ListTxns(ctx, &pb.ListTxnsRequest{CreatedBefore: t3.CreatedAt}) + require.NoError(t, err) + require.Len(t, res.Txns, 2) +} + +func TestListTxnsCreatedAfterBefore(t *testing.T) { + c, lc, dAddr, cleanup := requireSetup(t, ctx, 300) + defer cleanup() + addr1 := requireLotusAddress(t, ctx, lc) + t1 := requireSendFil(t, ctx, c, dAddr.String(), addr1.String(), oneFil, false) + requireSendFil(t, ctx, c, dAddr.String(), addr1.String(), oneFil, false) + t3 := requireSendFil(t, ctx, c, dAddr.String(), addr1.String(), oneFil, false) + res, err := c.ListTxns(ctx, &pb.ListTxnsRequest{CreatedAfter: t1.CreatedAt, CreatedBefore: t3.CreatedAt}) + require.NoError(t, err) + require.Len(t, res.Txns, 1) +} + +func TestListTxnsUpdatedAfter(t *testing.T) { + c, lc, dAddr, cleanup := requireSetup(t, ctx, 300) + defer cleanup() + addr1 := requireLotusAddress(t, ctx, lc) + t1 := requireSendFil(t, ctx, c, dAddr.String(), addr1.String(), oneFil, false) + requireSendFil(t, ctx, c, dAddr.String(), addr1.String(), oneFil, false) + requireSendFil(t, ctx, c, dAddr.String(), addr1.String(), oneFil, false) + res, err := c.ListTxns(ctx, &pb.ListTxnsRequest{UpdatedAfter: t1.UpdatedAt}) + require.NoError(t, err) + require.Len(t, res.Txns, 2) +} + +func TestListTxnsUpdatedBefore(t *testing.T) { + c, lc, dAddr, cleanup := requireSetup(t, ctx, 300) + defer cleanup() + addr1 := requireLotusAddress(t, ctx, lc) + requireSendFil(t, ctx, c, dAddr.String(), addr1.String(), oneFil, false) + requireSendFil(t, ctx, c, dAddr.String(), addr1.String(), oneFil, false) + t3 := requireSendFil(t, ctx, c, dAddr.String(), addr1.String(), oneFil, false) + res, err := c.ListTxns(ctx, &pb.ListTxnsRequest{UpdatedBefore: t3.UpdatedAt}) + require.NoError(t, err) + require.Len(t, res.Txns, 2) +} + +func TestListTxnsUpdatedAfterBefore(t *testing.T) { + c, lc, dAddr, cleanup := requireSetup(t, ctx, 300) + defer cleanup() + addr1 := requireLotusAddress(t, ctx, lc) + t1 := requireSendFil(t, ctx, c, dAddr.String(), addr1.String(), oneFil, false) + requireSendFil(t, ctx, c, dAddr.String(), addr1.String(), oneFil, false) + t3 := requireSendFil(t, ctx, c, dAddr.String(), addr1.String(), oneFil, false) + res, err := c.ListTxns(ctx, &pb.ListTxnsRequest{UpdatedAfter: t1.UpdatedAt, UpdatedBefore: t3.UpdatedAt}) + require.NoError(t, err) + require.Len(t, res.Txns, 1) +} + +func TestListTxnsOrder(t *testing.T) { + c, lc, dAddr, cleanup := requireSetup(t, ctx, 300) + defer cleanup() + addr1 := requireLotusAddress(t, ctx, lc) + requireSendFil(t, ctx, c, dAddr.String(), addr1.String(), oneFil, false) + requireSendFil(t, ctx, c, dAddr.String(), addr1.String(), oneFil, false) + requireSendFil(t, ctx, c, dAddr.String(), addr1.String(), oneFil, false) + res, err := c.ListTxns(ctx, &pb.ListTxnsRequest{Ascending: false}) + require.NoError(t, err) + require.Len(t, res.Txns, 3) + requireTxnsOrder(t, res.Txns, false) + res, err = c.ListTxns(ctx, &pb.ListTxnsRequest{Ascending: true}) + require.NoError(t, err) + require.Len(t, res.Txns, 3) + requireTxnsOrder(t, res.Txns, true) +} + +func TestListTxnsPaging(t *testing.T) { + c, lc, dAddr, cleanup := requireSetup(t, ctx, 300) + defer cleanup() + addr1 := requireLotusAddress(t, ctx, lc) + txFirst := requireSendFil(t, ctx, c, dAddr.String(), addr1.String(), oneFil, false) + requireSendFil(t, ctx, c, dAddr.String(), addr1.String(), oneFil, false) + requireSendFil(t, ctx, c, dAddr.String(), addr1.String(), oneFil, false) + requireSendFil(t, ctx, c, dAddr.String(), addr1.String(), oneFil, false) + requireSendFil(t, ctx, c, dAddr.String(), addr1.String(), oneFil, false) + requireSendFil(t, ctx, c, dAddr.String(), addr1.String(), oneFil, false) + requireSendFil(t, ctx, c, dAddr.String(), addr1.String(), oneFil, false) + requireSendFil(t, ctx, c, dAddr.String(), addr1.String(), oneFil, false) + requireSendFil(t, ctx, c, dAddr.String(), addr1.String(), oneFil, false) + txLast := requireSendFil(t, ctx, c, dAddr.String(), addr1.String(), oneFil, false) + + pageResults := func(ascending bool) { + numPages := 0 + more := true + var moreToken int64 = 0 + for more { + req := &pb.ListTxnsRequest{CreatedAfter: txFirst.CreatedAt, CreatedBefore: txLast.CreatedAt, Limit: 3, Ascending: ascending} + if moreToken != 0 { + req.MoreToken = moreToken + } + res, err := c.ListTxns(ctx, req) + require.NoError(t, err) + requireTxnsOrder(t, res.Txns, ascending) + numPages++ + if numPages < 3 { + require.True(t, res.More) + require.Greater(t, res.MoreToken, int64(0)) + require.Len(t, res.Txns, 3) + } + if numPages == 3 { + require.False(t, res.More) + require.Equal(t, int64(0), res.MoreToken) + require.Len(t, res.Txns, 2) + } + moreToken = res.MoreToken + more = res.More + } + require.Equal(t, 3, numPages) + } + pageResults(false) + pageResults(true) +} + +func TestSummary(t *testing.T) { + c, lc, dAddr, cleanup := requireSetup(t, ctx, 1000) + defer cleanup() + addr1 := requireLotusAddress(t, ctx, lc) + addr2 := requireLotusAddress(t, ctx, lc) + txFirst := requireSendFil(t, ctx, c, dAddr.String(), addr2.String(), oneFil*3, true) + requireSendFil(t, ctx, c, dAddr.String(), addr1.String(), oneFil*2, false) + requireSendFil(t, ctx, c, dAddr.String(), addr1.String(), oneFil*2, false) + txLast := requireSendFil(t, ctx, c, addr2.String(), addr1.String(), oneFil, false) + time.Sleep(time.Millisecond * 100) // Little time to allow the monitoring process to start waiting for all the txns. + res, err := c.Summary(ctx, &pb.SummaryRequest{}) + require.NoError(t, err) + require.Equal(t, float64(oneFil*2), res.AvgNanoFilSent) + require.Equal(t, int64(1), res.CountActive) + require.Equal(t, int64(0), res.CountFailed) + require.Equal(t, int64(2), res.CountFromAddrs) + require.Equal(t, int64(3), res.CountPending) + require.Equal(t, int64(2), res.CountToAddrs) + require.Equal(t, int64(4), res.CountTxns) + require.Equal(t, int64(3), res.CountWaiting) + require.Equal(t, int64(oneFil*3), res.MaxNanoFilSent) + require.Equal(t, int64(oneFil), res.MinNanoFilSent) + require.Equal(t, int64(oneFil*8), res.TotalNanoFilSent) + res, err = c.Summary(ctx, &pb.SummaryRequest{After: txFirst.CreatedAt, Before: txLast.CreatedAt}) + require.NoError(t, err) + require.Equal(t, float64(oneFil*2), res.AvgNanoFilSent) + require.Equal(t, int64(0), res.CountActive) + require.Equal(t, int64(0), res.CountFailed) + require.Equal(t, int64(1), res.CountFromAddrs) + require.Equal(t, int64(2), res.CountPending) + require.Equal(t, int64(1), res.CountToAddrs) + require.Equal(t, int64(2), res.CountTxns) + require.Equal(t, int64(2), res.CountWaiting) + require.Equal(t, int64(oneFil*2), res.MaxNanoFilSent) + require.Equal(t, int64(oneFil*2), res.MinNanoFilSent) + require.Equal(t, int64(oneFil*4), res.TotalNanoFilSent) +} + +func requireSetup(t *testing.T, ctx context.Context, speed int) (pb.SendFilServiceClient, *apistruct.FullNodeStruct, address.Address, func()) { + clientBuilder, addr, _ := tests.CreateLocalDevnet(t, 1, speed) time.Sleep(time.Millisecond * 500) // Allow the network to some tipsets listener := bufconn.Listen(bufSize) @@ -116,3 +516,37 @@ func requireLotusAddress(t *testing.T, ctx context.Context, lotusClient *apistru require.Greater(t, len(addr.String()), 0) return addr } + +func requireSendFil(t *testing.T, ctx context.Context, c pb.SendFilServiceClient, from, to string, amt int64, wait bool) *pb.Txn { + res, err := c.SendFil(ctx, &pb.SendFilRequest{From: from, To: to, AmountNanoFil: amt, Wait: wait}) + require.NoError(t, err) + require.Equal(t, from, res.Txn.From) + require.Equal(t, to, res.Txn.To) + require.Equal(t, amt, res.Txn.AmountNanoFil) + require.NotEmpty(t, res.Txn.MessageCid) + return res.Txn +} + +func requireTxnsOrder(t *testing.T, txns []*pb.Txn, ascending bool) { + var last *time.Time + for _, txn := range txns { + if last != nil { + a := *last + b := txn.CreatedAt.AsTime() + if ascending { + a = txn.CreatedAt.AsTime() + b = *last + } + require.True(t, a.After(b)) + } + t := txn.CreatedAt.AsTime() + last = &t + } +} + +func randomCid() cid.Cid { + data := make([]byte, 20) + rand.Read(data) + hash, _ := mh.Sum(data, mh.SHA2_256, -1) + return cid.NewCidV1(cid.DagCBOR, hash) +} diff --git a/go.mod b/go.mod index 107cd8c89..3f55a357f 100644 --- a/go.mod +++ b/go.mod @@ -13,9 +13,9 @@ require ( github.com/cloudflare/cloudflare-go v0.11.6 github.com/customerio/go-customerio v2.0.0+incompatible github.com/dgrijalva/jwt-go v3.2.0+incompatible - github.com/filecoin-project/go-address v0.0.5-0.20201103152444-f2023ef3f5bb - github.com/filecoin-project/go-fil-markets v1.0.10 - github.com/filecoin-project/lotus v1.4.0 + github.com/filecoin-project/go-address v0.0.5 + github.com/filecoin-project/go-fil-markets v1.1.7 + github.com/filecoin-project/lotus v1.4.2 github.com/gin-contrib/location v0.0.2 github.com/gin-contrib/static v0.0.0-20191128031702-f81c604d8ac2 github.com/gin-gonic/gin v1.6.3 @@ -62,27 +62,27 @@ require ( github.com/rs/cors v1.7.0 github.com/russross/blackfriday/v2 v2.1.0 // indirect github.com/segmentio/backo-go v0.0.0-20200129164019-23eae7c10bd3 // indirect - github.com/sirupsen/logrus v1.7.0 // indirect github.com/spf13/afero v1.2.2 // indirect github.com/spf13/cast v1.3.1 // indirect github.com/spf13/cobra v1.1.1 github.com/spf13/jwalterweatherman v1.1.0 // indirect github.com/spf13/viper v1.7.1 - github.com/stretchr/testify v1.6.1 + github.com/stretchr/objx v0.2.0 // indirect + github.com/stretchr/testify v1.7.0 github.com/stripe/stripe-go/v72 v72.10.0 github.com/textileio/dcrypto v0.0.1 github.com/textileio/go-assets v0.0.0-20200430191519-b341e634e2b7 github.com/textileio/go-ds-mongo v0.1.5-0.20201230201018-2b7fdca787a5 github.com/textileio/go-threads v1.0.3-0.20201216032729-f7b034a0de80 - github.com/textileio/powergate/v2 v2.0.0 + github.com/textileio/powergate/v2 v2.1.1-0.20210226193238-217dae95e6e1 github.com/xakep666/mongo-migrate v0.2.1 github.com/xtgo/uuid v0.0.0-20140804021211-a0b114877d4c // indirect go.mongodb.org/mongo-driver v1.4.1 - golang.org/x/net v0.0.0-20201021035429-f5854403a974 - golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9 + golang.org/x/net v0.0.0-20201110031124-69a78807bb2b + golang.org/x/sync v0.0.0-20201207232520-09787c993a3a golang.org/x/sys v0.0.0-20201218084310-7d0127a74742 // indirect golang.org/x/time v0.0.0-20200416051211-89c76fbcd5d1 // indirect - google.golang.org/grpc v1.34.0 + google.golang.org/grpc v1.35.0 google.golang.org/grpc/examples v0.0.0-20200819190100-f640ae6a4f43 // indirect google.golang.org/protobuf v1.25.0 gopkg.in/ini.v1 v1.55.0 // indirect diff --git a/go.sum b/go.sum index 9dde7ac0e..03ee1b53c 100644 --- a/go.sum +++ b/go.sum @@ -153,8 +153,9 @@ github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= github.com/cespare/xxhash/v2 v2.1.0/go.mod h1:dgIUBU3pDso/gPgZ1osOZ0iQf77oPR28Tjxl5dIMyVM= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/charmbracelet/bubbles v0.7.5/go.mod h1:IRTORFvhEI6OUH7WhN2Ks8Z8miNGimk1BE6cmHijOkM= +github.com/charmbracelet/bubbles v0.7.6/go.mod h1:0D4XRYK0tjo8JMvflz1obpVcOikNZSG46SFauoZj22s= github.com/charmbracelet/bubbletea v0.12.2/go.mod h1:3gZkYELUOiEUOp0bTInkxguucy/xRbGSOcbMs1geLxg= +github.com/charmbracelet/bubbletea v0.12.4/go.mod h1:tp9tr9Dadh0PLhgiwchE5zZJXm5543JYjHG9oY+5qSg= github.com/cheekybits/genny v1.0.0/go.mod h1:+tQajlRqAUrPI7DOSpB0XAqZYtQakVtB7wXkRAgjxjQ= github.com/cheggaaa/pb/v3 v3.0.5 h1:lmZOti7CraK9RSjzExsY53+WWfub9Qv13B5m4ptEoPE= github.com/cheggaaa/pb/v3 v3.0.5/go.mod h1:X1L61/+36nz9bjIsrDU52qHKOQukUQe2Ge+YvGuquCw= @@ -164,12 +165,13 @@ github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e h1:fY5BOSpyZCqRo5O github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1 h1:q763qf9huN11kDQavWsoZXJNW3xEE4JJyHa5Q25/sd8= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= +github.com/cilium/ebpf v0.2.0/go.mod h1:To2CFviqOWL/M0gIMsvSMlqe7em/l1ALkX1PyjrX2Qs= github.com/clbanning/x2j v0.0.0-20191024224557-825249438eec/go.mod h1:jMjuTZXRI4dUb/I5gc9Hdhagfvm9+RyrPryS/auMzxE= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/cloudflare/cloudflare-go v0.11.6 h1:gErXaYucoS8aHdmoJnF4RMFiXJH449sk6rCtoP6EhrE= github.com/cloudflare/cloudflare-go v0.11.6/go.mod h1:lmCbgQdBeSQlMv0W0OSqoGgl8aFrgc5oXHhWMt47dh0= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= -github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= +github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8= github.com/cockroachdb/errors v1.2.4/go.mod h1:rQD95gz6FARkaKkQXUksEje/d9a6wBJoCr5oaCLELYA= github.com/cockroachdb/logtags v0.0.0-20190617123548-eb05cc24525f/go.mod h1:i/u985jwjWRlyHXQbwatDASoW0RMlZ/3i9yJHE2xLkI= @@ -177,6 +179,7 @@ github.com/cockroachdb/pebble v0.0.0-20200916222308-4e219a90ba5b/go.mod h1:hU7vh github.com/cockroachdb/pebble v0.0.0-20201001221639-879f3bfeef07/go.mod h1:hU7vhtrqonEphNF+xt8/lHdaBprxmV1h8BOGrd9XwmQ= github.com/cockroachdb/redact v0.0.0-20200622112456-cd282804bbd3/go.mod h1:BVNblN9mBWFyMyqK1k3AAiSxhvhfK2oOZZ2lK+dpvRg= github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI= +github.com/containerd/cgroups v0.0.0-20201119153540-4cbc285b3327/go.mod h1:ZJeTFisyysqgcCdecO57Dj79RfL0LNeGiFUqLYQRYLE= github.com/containerd/console v1.0.1/go.mod h1:XUsP6YE/mKtz6bxc+I8UiKKTP04qjQL4qcS3XoQ5xkw= github.com/containerd/continuity v0.0.0-20190827140505-75bee3e2ccb6/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y= github.com/containerd/continuity v0.0.0-20200228182428-0f16d7a0959c h1:8ahmSVELW1wghbjerVAyuEYD5+Dio66RYvSS0iGfL1M= @@ -193,7 +196,7 @@ github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7/go.mod h1:F5haX7 github.com/coreos/go-systemd v0.0.0-20181012123002-c6f51f82210d/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= github.com/coreos/go-systemd v0.0.0-20191104093116-d3cd4ed1dbcf/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= -github.com/coreos/go-systemd/v22 v22.0.0/go.mod h1:xO0FLkIi5MaZafQlIrOotqXZ90ih+1atmu1JpKERPPk= +github.com/coreos/go-systemd/v22 v22.1.0/go.mod h1:xO0FLkIi5MaZafQlIrOotqXZ90ih+1atmu1JpKERPPk= github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= github.com/cpuguy83/go-md2man v1.0.10 h1:BSKMNlYxDvnunlTymqtgONjNnaRV1sTpcovwwjF22jk= @@ -277,7 +280,7 @@ github.com/envoyproxy/go-control-plane v0.6.9/go.mod h1:SBwIajubJHhxtWwsL9s8ss4s github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= -github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po= +github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/evanphx/json-patch v4.5.0+incompatible h1:ouOWdg56aJriqS0huScTkVXPC5IcNrDCXZ6OoTAWu7M= github.com/evanphx/json-patch v4.5.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= @@ -295,17 +298,20 @@ github.com/filecoin-project/filecoin-ffi v0.30.4-0.20200910194244-f640612a1a1f/g github.com/filecoin-project/go-address v0.0.2-0.20200218010043-eb9bb40ed5be/go.mod h1:SAOwJoakQ8EPjwNIsiakIQKsoKdkcbx8U3IapgCg9R0= github.com/filecoin-project/go-address v0.0.3 h1:eVfbdjEbpbzIrbiSa+PiGUY+oDK9HnUn+M1R/ggoHf8= github.com/filecoin-project/go-address v0.0.3/go.mod h1:jr8JxKsYx+lQlQZmF5i2U0Z+cGQ59wMIps/8YW/lDj8= -github.com/filecoin-project/go-address v0.0.5-0.20201103152444-f2023ef3f5bb h1:Cbu7YYsXHtVlPEJ+eqbBx2S3ElmWCB0NjpGPYvvvCrA= -github.com/filecoin-project/go-address v0.0.5-0.20201103152444-f2023ef3f5bb/go.mod h1:jr8JxKsYx+lQlQZmF5i2U0Z+cGQ59wMIps/8YW/lDj8= +github.com/filecoin-project/go-address v0.0.5 h1:SSaFT/5aLfPXycUlFyemoHYhRgdyXClXCyDdNJKPlDM= +github.com/filecoin-project/go-address v0.0.5/go.mod h1:jr8JxKsYx+lQlQZmF5i2U0Z+cGQ59wMIps/8YW/lDj8= github.com/filecoin-project/go-amt-ipld/v2 v2.0.1-0.20200424220931-6263827e49f2/go.mod h1:boRtQhzmxNocrMxOXo1NYn4oUc1NGvR8tEa79wApNXg= github.com/filecoin-project/go-amt-ipld/v2 v2.1.0/go.mod h1:nfFPoGyX0CU9SkXX8EoCcSuHN1XcbN0c6KBh7yvP5fs= github.com/filecoin-project/go-amt-ipld/v2 v2.1.1-0.20201006184820-924ee87a1349 h1:pIuR0dnMD0i+as8wNnjjHyQrnhP5O5bmba/lmgQeRgU= github.com/filecoin-project/go-amt-ipld/v2 v2.1.1-0.20201006184820-924ee87a1349/go.mod h1:vgmwKBkx+ca5OIeEvstiQgzAZnb7R6QaqE1oEDSqa6g= +github.com/filecoin-project/go-amt-ipld/v3 v3.0.0 h1:Ou/q82QeHGOhpkedvaxxzpBYuqTxLCcj5OChkDNx4qc= +github.com/filecoin-project/go-amt-ipld/v3 v3.0.0/go.mod h1:Qa95YNAbtoVCTSVtX38aAC1ptBnJfPma1R/zZsKmx4o= github.com/filecoin-project/go-bitfield v0.0.1/go.mod h1:Ry9/iUlWSyjPUzlAvdnfy4Gtvrq4kWmWDztCU1yEgJY= github.com/filecoin-project/go-bitfield v0.2.0 h1:gCtLcjskIPtdg4NfN7gQZSQF9yrBQ7mkT0qCJxzGI2Q= github.com/filecoin-project/go-bitfield v0.2.0/go.mod h1:CNl9WG8hgR5mttCnUErjcQjGvuiZjRqK9rHVBsQF4oM= -github.com/filecoin-project/go-bitfield v0.2.3-0.20201110211213-fe2c1862e816 h1:RMdzMqe3mu2Z/3N3b9UEfkbGZxukstmZgNC024ybWhA= -github.com/filecoin-project/go-bitfield v0.2.3-0.20201110211213-fe2c1862e816/go.mod h1:CNl9WG8hgR5mttCnUErjcQjGvuiZjRqK9rHVBsQF4oM= +github.com/filecoin-project/go-bitfield v0.2.3/go.mod h1:CNl9WG8hgR5mttCnUErjcQjGvuiZjRqK9rHVBsQF4oM= +github.com/filecoin-project/go-bitfield v0.2.4 h1:uZ7MeE+XfM5lqrHJZ93OnhQKc/rveW8p9au0C68JPgk= +github.com/filecoin-project/go-bitfield v0.2.4/go.mod h1:CNl9WG8hgR5mttCnUErjcQjGvuiZjRqK9rHVBsQF4oM= github.com/filecoin-project/go-cbor-util v0.0.0-20191219014500-08c40a1e63a2 h1:av5fw6wmm58FYMgJeoB/lK9XXrgdugYiTqkdxjTy9k8= github.com/filecoin-project/go-cbor-util v0.0.0-20191219014500-08c40a1e63a2/go.mod h1:pqTiPHobNkOVM5thSRsHYjyQfq7O5QSCMhvuu9JoDlg= github.com/filecoin-project/go-commp-utils v0.0.0-20201119054358-b88f7a96a434 h1:0kHszkYP3hgApcjl5x4rpwONhN9+j7XDobf6at5XfHs= @@ -313,8 +319,8 @@ github.com/filecoin-project/go-commp-utils v0.0.0-20201119054358-b88f7a96a434/go github.com/filecoin-project/go-crypto v0.0.0-20191218222705-effae4ea9f03 h1:2pMXdBnCiXjfCYx/hLqFxccPoqsSveQFxVLvNxy9bus= github.com/filecoin-project/go-crypto v0.0.0-20191218222705-effae4ea9f03/go.mod h1:+viYnvGtUTgJRdy6oaeF4MTFKAfatX071MPDPBL11EQ= github.com/filecoin-project/go-data-transfer v1.0.1/go.mod h1:UxvfUAY9v3ub0a21BSK9u3pB2aq30Y0KMsG+w9/ysyo= -github.com/filecoin-project/go-data-transfer v1.2.3 h1:rM/HgGOOMsKvmeQjY7CVR3v7Orxf04LJSSczSpGlhg4= -github.com/filecoin-project/go-data-transfer v1.2.3/go.mod h1:ZAH51JZFR8NZC4FPiDPG+swjgui0q6zTMJbztc6pHhY= +github.com/filecoin-project/go-data-transfer v1.2.7 h1:WE5Cpp9eMt5BDoWOVR64QegSn6bwHQaDzyyjVU377Y0= +github.com/filecoin-project/go-data-transfer v1.2.7/go.mod h1:mvjZ+C3NkBX10JP4JMu27DCjUouHFjHwUGh+Xc4yvDA= github.com/filecoin-project/go-ds-versioning v0.1.0 h1:y/X6UksYTsK8TLCI7rttCKEvl8btmWxyFMEeeWGUxIQ= github.com/filecoin-project/go-ds-versioning v0.1.0/go.mod h1:mp16rb4i2QPmxBnmanUx8i/XANp+PFCCJWiAb+VW4/s= github.com/filecoin-project/go-fil-commcid v0.0.0-20200716160307-8f644712406f h1:GxJzR3oRIMTPtpZ0b7QF8FKPK6/iPAc7trhlL5k/g+s= @@ -322,14 +328,16 @@ github.com/filecoin-project/go-fil-commcid v0.0.0-20200716160307-8f644712406f/go github.com/filecoin-project/go-fil-commcid v0.0.0-20201016201715-d41df56b4f6a h1:hyJ+pUm/4U4RdEZBlg6k8Ma4rDiuvqyGpoICXAxwsTg= github.com/filecoin-project/go-fil-commcid v0.0.0-20201016201715-d41df56b4f6a/go.mod h1:Eaox7Hvus1JgPrL5+M3+h7aSPHc0cVqpSxA+TxIEpZQ= github.com/filecoin-project/go-fil-markets v1.0.5-0.20201113164554-c5eba40d5335/go.mod h1:AJySOJC00JRWEZzRG2KsfUnqEf5ITXxeX09BE9N4f9c= -github.com/filecoin-project/go-fil-markets v1.0.10 h1:1QunPsgApTLNXVlaXoPMxyrMtOsMLPOQq3RUjGRmgVI= -github.com/filecoin-project/go-fil-markets v1.0.10/go.mod h1:tcXby9CsTNuHu19dH05YZ5pNDsoYcQXSrbkxzVeMJrY= +github.com/filecoin-project/go-fil-markets v1.1.7 h1:7yy7alIDWzUxljxZhGmG3+wvaU4Ty5QDMbPmdZeaIJ8= +github.com/filecoin-project/go-fil-markets v1.1.7/go.mod h1:6oTRaAsHnCqhi3mpZqdvnWIzH6QzHQc4dbhJrI9/BfQ= github.com/filecoin-project/go-hamt-ipld v0.1.5 h1:uoXrKbCQZ49OHpsTCkrThPNelC4W3LPEk0OrS/ytIBM= github.com/filecoin-project/go-hamt-ipld v0.1.5/go.mod h1:6Is+ONR5Cd5R6XZoCse1CWaXZc0Hdb/JeX+EQCQzX24= github.com/filecoin-project/go-hamt-ipld/v2 v2.0.0 h1:b3UDemBYN2HNfk3KOXNuxgTTxlWi3xVvbQP0IT38fvM= github.com/filecoin-project/go-hamt-ipld/v2 v2.0.0/go.mod h1:7aWZdaQ1b16BVoQUYR+eEvrDCGJoPLxFpDynFjYfBjI= -github.com/filecoin-project/go-jsonrpc v0.1.2 h1:MTebUawBHLxxY9gDi1WXuGc89TWIDmsgoDqeZSk9KRw= -github.com/filecoin-project/go-jsonrpc v0.1.2/go.mod h1:XBBpuKIMaXIIzeqzO1iucq4GvbF8CxmXRFoezRh+Cx4= +github.com/filecoin-project/go-hamt-ipld/v3 v3.0.1 h1:zbzs46G7bOctkZ+JUX3xirrj0RaEsi+27dtlsgrTNBg= +github.com/filecoin-project/go-hamt-ipld/v3 v3.0.1/go.mod h1:gXpNmr3oQx8l3o7qkGyDjJjYSRX7hp/FGOStdqrWyDI= +github.com/filecoin-project/go-jsonrpc v0.1.4-0.20210217175800-45ea43ac2bec h1:rGI5I7fdU4viManxmDdbk5deZO7afe6L1Wc04dAmlOM= +github.com/filecoin-project/go-jsonrpc v0.1.4-0.20210217175800-45ea43ac2bec/go.mod h1:XBBpuKIMaXIIzeqzO1iucq4GvbF8CxmXRFoezRh+Cx4= github.com/filecoin-project/go-multistore v0.0.3 h1:vaRBY4YiA2UZFPK57RNuewypB8u0DzzQwqsL0XarpnI= github.com/filecoin-project/go-multistore v0.0.3/go.mod h1:kaNqCC4IhU4B1uyr7YWFHd23TL4KM32aChS0jNkyUvQ= github.com/filecoin-project/go-padreader v0.0.0-20200903213702-ed5fae088b20 h1:+/4aUeUoKr6AKfPE3mBhXA5spIV6UcKdTYDPNU2Tdmg= @@ -341,14 +349,16 @@ github.com/filecoin-project/go-state-types v0.0.0-20200904021452-1883f36ca2f4/go github.com/filecoin-project/go-state-types v0.0.0-20200928172055-2df22083d8ab/go.mod h1:ezYnPf0bNkTsDibL/psSz5dy4B5awOJ/E7P2Saeep8g= github.com/filecoin-project/go-state-types v0.0.0-20201102161440-c8033295a1fc h1:+hbMY4Pcx2oizrfH08VWXwrj5mU8aJT6g0UNxGHFCGU= github.com/filecoin-project/go-state-types v0.0.0-20201102161440-c8033295a1fc/go.mod h1:ezYnPf0bNkTsDibL/psSz5dy4B5awOJ/E7P2Saeep8g= +github.com/filecoin-project/go-state-types v0.0.0-20210119062722-4adba5aaea71 h1:Cas/CUB4ybYpdxvW7LouaydE16cpwdq3vvS3qgZuU+Q= +github.com/filecoin-project/go-state-types v0.0.0-20210119062722-4adba5aaea71/go.mod h1:ezYnPf0bNkTsDibL/psSz5dy4B5awOJ/E7P2Saeep8g= github.com/filecoin-project/go-statemachine v0.0.0-20200925024713-05bd7c71fbfe h1:dF8u+LEWeIcTcfUcCf3WFVlc81Fr2JKg8zPzIbBDKDw= github.com/filecoin-project/go-statemachine v0.0.0-20200925024713-05bd7c71fbfe/go.mod h1:FGwQgZAt2Gh5mjlwJUlVB62JeYdo+if0xWxSEfBD9ig= github.com/filecoin-project/go-statestore v0.1.0 h1:t56reH59843TwXHkMcwyuayStBIiWBRilQjQ+5IiwdQ= github.com/filecoin-project/go-statestore v0.1.0/go.mod h1:LFc9hD+fRxPqiHiaqUEZOinUJB4WARkRfNl10O7kTnI= github.com/filecoin-project/go-storedcounter v0.0.0-20200421200003-1c99c62e8a5b h1:fkRZSPrYpk42PV3/lIXiL0LHetxde7vyYYvSsttQtfg= github.com/filecoin-project/go-storedcounter v0.0.0-20200421200003-1c99c62e8a5b/go.mod h1:Q0GQOBtKf1oE10eSXSlhN45kDBdGvEcVOqMiffqX+N8= -github.com/filecoin-project/lotus v1.4.0 h1:TxlV/T+ipO75egC8vbj9Hxf3z4FBvmsewukR792fFbk= -github.com/filecoin-project/lotus v1.4.0/go.mod h1:a5VLzvaVuIj8859qDykebsY+mjcj0CL6gymmua8Dl8k= +github.com/filecoin-project/lotus v1.4.2 h1:s7cncb881O9c4uWVU4bjJpQY/ANtuGiKUFTgI00LxuI= +github.com/filecoin-project/lotus v1.4.2/go.mod h1:+tmCnqmSGrJp5CNyuXai1CCAFRKj50HKaKrpy2S/X5c= github.com/filecoin-project/specs-actors v0.6.1/go.mod h1:dRdy3cURykh2R8O/DKqy8olScl70rmIS7GrB4hB1IDY= github.com/filecoin-project/specs-actors v0.9.4/go.mod h1:BStZQzx5x7TmCkLv0Bpa07U6cPKol6fd3w9KjMPZ6Z4= github.com/filecoin-project/specs-actors v0.9.12 h1:iIvk58tuMtmloFNHhAOQHG+4Gci6Lui0n7DYQGi3cJk= @@ -358,8 +368,10 @@ github.com/filecoin-project/specs-actors v0.9.13/go.mod h1:TS1AW/7LbG+615j4NsjMK github.com/filecoin-project/specs-actors/v2 v2.0.1/go.mod h1:v2NZVYinNIKA9acEMBm5wWXxqv5+frFEbekBFemYghY= github.com/filecoin-project/specs-actors/v2 v2.3.2 h1:2Vcf4CGa29kRh4JJ02m+FbvD/p3YNnLGsaHfw7Uj49g= github.com/filecoin-project/specs-actors/v2 v2.3.2/go.mod h1:UuJQLoTx/HPvvWeqlIFmC/ywlOLHNe8SNQ3OunFbu2Y= -github.com/filecoin-project/specs-actors/v2 v2.3.3 h1:5Pd6pjU7VjUye+Hz4gYBCPAFdBxtEbHsgGYvWmfc83w= -github.com/filecoin-project/specs-actors/v2 v2.3.3/go.mod h1:UuJQLoTx/HPvvWeqlIFmC/ywlOLHNe8SNQ3OunFbu2Y= +github.com/filecoin-project/specs-actors/v2 v2.3.4 h1:NZK2oMCcA71wNsUzDBmLQyRMzcCnX9tDGvwZ53G67j8= +github.com/filecoin-project/specs-actors/v2 v2.3.4/go.mod h1:UuJQLoTx/HPvvWeqlIFmC/ywlOLHNe8SNQ3OunFbu2Y= +github.com/filecoin-project/specs-actors/v3 v3.0.1-0.20210128235937-57195d8909b1 h1:I6mvbwANIoToUZ37cYmuLyDKbPlAUxWnp0fJOZnlTz4= +github.com/filecoin-project/specs-actors/v3 v3.0.1-0.20210128235937-57195d8909b1/go.mod h1:NL24TPjJGyU7fh1ztpUyYcoZi3TmRKNEI0huPYmhObA= github.com/filecoin-project/specs-storage v0.1.1-0.20201105051918-5188d9774506 h1:Ur/l2+6qN+lQiqjozWWc5p9UDaAMDZKTlDS98oRnlIw= github.com/filecoin-project/specs-storage v0.1.1-0.20201105051918-5188d9774506/go.mod h1:nJRRM7Aa9XVvygr3W9k6xGF46RWzr2zxF/iGoAIfA/g= github.com/filecoin-project/test-vectors/schema v0.0.5/go.mod h1:iQ9QXLpYWL3m7warwvK1JC/pTri8mnfEmKygNDqqY6E= @@ -499,6 +511,8 @@ github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMyw github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.4 h1:L8R9j+yAqZuZjsqh/z+F1NCffTKKLShY6zXTItVIZ8M= github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-github v17.0.0+incompatible h1:N0LgJ1j65A7kfXrZnUDaYCs/Sf4rEjNlfyDHW9dolSY= @@ -524,8 +538,8 @@ github.com/google/uuid v1.1.1 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY= github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.2 h1:EVhdT+1Kseyi1/pUmXKaFxYsDNy9RQYkMWRH68J/W7Y= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/google/uuid v1.1.5 h1:kxhtnfFVi+rYdOALN0B3k9UT86zVJKfBimRaciULW4I= -github.com/google/uuid v1.1.5/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.2.0 h1:qJYtXnJRWmpe7m/3XlyhrsLrEURqHRM2kxzoxXqyUDs= +github.com/google/uuid v1.2.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/googleapis/gax-go v2.0.0+incompatible/go.mod h1:SFVmujtThgffbyetf+mdk2eWhX2bMyUtNHzFKcPA9HY= github.com/googleapis/gax-go/v2 v2.0.3/go.mod h1:LLvjysVCY1JZeum8Z6l8qUty8fiNwE08qbEPm1M08qg= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= @@ -697,10 +711,8 @@ github.com/ipfs/go-graphsync v0.1.0 h1:RjLk7ha1tJtDXktqoxOjhvx4lDuzzIU+xQ+PEi74r github.com/ipfs/go-graphsync v0.1.0/go.mod h1:jMXfqIEDFukLPZHqDPp8tJMbHO9Rmeb9CEGevngQbmE= github.com/ipfs/go-graphsync v0.4.2/go.mod h1:/VmbZTUdUMTbNkgzAiCEucIIAU3BkLE2cZrDCVUhyi0= github.com/ipfs/go-graphsync v0.4.3/go.mod h1:mPOwDYv128gf8gxPFgXnz4fNrSYPsWyqisJ7ych+XDY= -github.com/ipfs/go-graphsync v0.5.0 h1:iaByvxq88Ys1KcaQzTS1wmRhNsNEo3SaUiSGqTSbGmM= -github.com/ipfs/go-graphsync v0.5.0/go.mod h1:e2ZxnClqBBYAtd901g9vXMJzS47labjAtOzsWtOzKNk= -github.com/ipfs/go-graphsync v0.5.1 h1:4fXBRvRKicTgTmCFMmEua/H5jvmAOLgU9Z7PCPWt2ec= -github.com/ipfs/go-graphsync v0.5.1/go.mod h1:e2ZxnClqBBYAtd901g9vXMJzS47labjAtOzsWtOzKNk= +github.com/ipfs/go-graphsync v0.5.2 h1:USD+daaSC+7pLHCxROThSaF6SF7WYXF03sjrta0rCfA= +github.com/ipfs/go-graphsync v0.5.2/go.mod h1:e2ZxnClqBBYAtd901g9vXMJzS47labjAtOzsWtOzKNk= github.com/ipfs/go-hamt-ipld v0.0.15-0.20200131012125-dd88a59d3f2e/go.mod h1:9aQJu/i/TaRDW6jqB5U217dLIDopn50wxLdHXM2CTfE= github.com/ipfs/go-hamt-ipld v0.1.1 h1:0IQdvwnAAUKmDE+PMJa5y1QiwOPHpI9+eAbQEEEYthk= github.com/ipfs/go-hamt-ipld v0.1.1/go.mod h1:1EZCr2v0jlCnhpa+aZ0JZYp8Tt2w16+JJOAVz17YcDk= @@ -914,6 +926,8 @@ github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFB github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.2.0 h1:s5hAObm+yFO5uHYt5dYjxi2rXrsnmRpJx4OYvIWUaQs= github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= +github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI= +github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/pty v1.1.3/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= @@ -1107,6 +1121,8 @@ github.com/libp2p/go-libp2p-pubsub v0.1.1/go.mod h1:ZwlKzRSe1eGvSIdU5bD7+8RZN/Uz github.com/libp2p/go-libp2p-pubsub v0.3.2-0.20200527132641-c0712c6e92cf/go.mod h1:TxPOBuo1FPdsTjFnv+FGZbNbWYsp74Culx+4ViQpato= github.com/libp2p/go-libp2p-pubsub v0.4.0 h1:YNVRyXqBgv9i4RG88jzoTtkSOaSB45CqHkL29NNBZb4= github.com/libp2p/go-libp2p-pubsub v0.4.0/go.mod h1:izkeMLvz6Ht8yAISXjx60XUQZMq9ZMe5h2ih4dLIBIQ= +github.com/libp2p/go-libp2p-pubsub v0.4.1 h1:j4umIg5nyus+sqNfU+FWvb9aeYFQH/A+nDFhWj+8yy8= +github.com/libp2p/go-libp2p-pubsub v0.4.1/go.mod h1:izkeMLvz6Ht8yAISXjx60XUQZMq9ZMe5h2ih4dLIBIQ= github.com/libp2p/go-libp2p-quic-transport v0.1.1/go.mod h1:wqG/jzhF3Pu2NrhJEvE+IE0NTHNXslOPn9JQzyCAxzU= github.com/libp2p/go-libp2p-quic-transport v0.5.0/go.mod h1:IEcuC5MLxvZ5KuHKjRu+dr3LjCT1Be3rcD/4d8JrX8M= github.com/libp2p/go-libp2p-quic-transport v0.9.0/go.mod h1:xyY+IgxL0qsW7Kiutab0+NlxM0/p9yRtrGTYsuMWf70= @@ -1308,6 +1324,8 @@ github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzp github.com/mattn/go-runewidth v0.0.7/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= github.com/mattn/go-runewidth v0.0.9 h1:Lm995f3rfxdpd6TSmuVCHVb/QhupuXlYr8sCI/QdE+0= github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= +github.com/mattn/go-runewidth v0.0.10 h1:CoZ3S2P7pvtP45xOtBw+/mDL2z0RKI576gSkzRRpdGg= +github.com/mattn/go-runewidth v0.0.10/go.mod h1:RAqKPSqVFrSLVXbA8x7dzmKdmGzieGRCM46jaSJTDAk= github.com/mattn/go-xmlrpc v0.0.3/go.mod h1:mqc2dz7tP5x5BKlCahN/n+hs7OSZKJkS9JsHNBRlrxA= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= github.com/mdlayher/genetlink v1.0.0/go.mod h1:0rJ0h4itni50A86M2kHcgS85ttZazNt7a8H2a2cw0Gc= @@ -1359,6 +1377,8 @@ github.com/mr-tron/base58 v1.1.2/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjW github.com/mr-tron/base58 v1.1.3/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc= github.com/mr-tron/base58 v1.2.0 h1:T/HDJBh4ZCPbU39/+c3rRvE0uKBQlU27+QI8LJ4t64o= github.com/mr-tron/base58 v1.2.0/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc= +github.com/muesli/reflow v0.2.0/go.mod h1:qT22vjVmM9MIUeLgsVYe/Ye7eZlbv9dZjL3dVhUqLX8= +github.com/muesli/reflow v0.2.1-0.20210115123740-9e1d0d53df68/go.mod h1:Xk+z4oIWdQqJzsxyjgl3P22oYZnHdZ8FFTHAQQt5BMQ= github.com/muesli/termenv v0.7.2/go.mod h1:ct2L5N2lmix82RaY3bMWwVu/jUFc9Ule0KGDCiKYPh8= github.com/muesli/termenv v0.7.4/go.mod h1:pZ7qY9l3F7e5xsAOS0zCew2tME+p7bWeBkotCEcIIcc= github.com/multiformats/go-base32 v0.0.3 h1:tw5+NhuwaOjJCC5Pp82QuXbrmLzWg7uxlMFp8Nq/kkI= @@ -1434,6 +1454,8 @@ github.com/nats-io/nkeys v0.1.3/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxzi github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c= github.com/neelance/astrewrite v0.0.0-20160511093645-99348263ae86/go.mod h1:kHJEU3ofeGjhHklVoIGuVj85JJwZ6kWPaJwCIxgnFmo= github.com/neelance/sourcemap v0.0.0-20151028013722-8c68805598ab/go.mod h1:Qr6/a/Q4r9LP1IltGz7tA7iOK1WonHEYhu1HRBA7ZiM= +github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs= +github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= github.com/nikkolasg/hexjson v0.0.0-20181101101858-78e39397e00c/go.mod h1:7qN3Y0BvzRUf4LofcoJplQL10lsFDb4PYlePTVwrP28= github.com/nishanths/predeclared v0.0.0-20200524104333-86fad755b4d3/go.mod h1:nt3d53pc1VYcphSCIaYAJtnPYnr3Zyn8fMq2wvPGPso= github.com/nkovacs/streamquote v0.0.0-20170412213628-49af9bddb229/go.mod h1:0aYXnNPJ8l7uZxf45rWW1a/uME32OF0rhiYGNQ2oF2E= @@ -1479,6 +1501,7 @@ github.com/opencontainers/image-spec v1.0.1 h1:JMemWkRwHx4Zj+fVxWoMCFm/8sYGGrUVo github.com/opencontainers/image-spec v1.0.1/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0= github.com/opencontainers/runc v1.0.0-rc9 h1:/k06BMULKF5hidyoZymkoDCzdJzltZpz/UU4LguQVtc= github.com/opencontainers/runc v1.0.0-rc9/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U= +github.com/opencontainers/runtime-spec v1.0.2/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= github.com/opentracing-contrib/go-grpc v0.0.0-20180928155321-4b5a12d3ff02/go.mod h1:JNdpVEzCpXBgIiv4ds+TzhN1hrtxq6ClLrTlT9OQRSc= github.com/opentracing-contrib/go-grpc v0.0.0-20191001143057-db30781987df/go.mod h1:DYR5Eij8rJl8h7gblRrOZ8g0kW1umSpKqYIBTgeDtLo= github.com/opentracing-contrib/go-observer v0.0.0-20170622124052-a52f23424492/go.mod h1:Ngi6UdF0k5OKD5t5wlmGhe/EDKPoUM3BXZSSfIuJbis= @@ -1500,7 +1523,7 @@ github.com/oschwald/geoip2-golang v1.4.0 h1:5RlrjCgRyIGDz/mBmPfnAF4h8k0IAcRv9Pvr github.com/oschwald/geoip2-golang v1.4.0/go.mod h1:8QwxJvRImBH+Zl6Aa6MaIcs5YdlZSTKtzmPGzQqi9ng= github.com/oschwald/maxminddb-golang v1.6.0 h1:KAJSjdHQ8Kv45nFIbtoLGrGWqHFajOIm7skTyz/+Dls= github.com/oschwald/maxminddb-golang v1.6.0/go.mod h1:DUJFucBg2cvqx42YmDa/+xHvb0elJtOm3o4aFQ/nb/w= -github.com/otiai10/copy v1.3.0/go.mod h1:XWfuS3CrI0R6IE0FbgHsEazaXO8G0LpMp9o8tos0x4E= +github.com/otiai10/copy v1.4.2/go.mod h1:XWfuS3CrI0R6IE0FbgHsEazaXO8G0LpMp9o8tos0x4E= github.com/otiai10/curr v0.0.0-20150429015615-9b4961190c95/go.mod h1:9qAhocn7zKJG+0mI8eUu6xqkFDYS2kb2saOteoSB3cE= github.com/otiai10/curr v1.0.0/go.mod h1:LskTG5wDwr8Rs+nNQ+1LlxRjAtTZZjtJW4rMXl6j4vs= github.com/otiai10/mint v1.3.0/go.mod h1:F5AjcsTsWUqX+Na9fpHb52P8pcRX2CI6A3ctIT91xUo= @@ -1583,12 +1606,15 @@ github.com/rainycape/unidecode v0.0.0-20150907023854-cb7f23ec59be h1:ta7tUOvsPHV github.com/rainycape/unidecode v0.0.0-20150907023854-cb7f23ec59be/go.mod h1:MIDFMn7db1kT65GmV94GzpX9Qdi7N/pQlwb+AN8wh+Q= github.com/raulk/clock v1.1.0 h1:dpb29+UKMbLqiU/jqIJptgLR1nn23HLgMY0sTCDza5Y= github.com/raulk/clock v1.1.0/go.mod h1:3MpVxdZ/ODBQDxbN+kzshf5OSZwPjtMDx6BBXBmOeY0= -github.com/raulk/go-watchdog v0.0.1/go.mod h1:dIvQcKy0laxuHGda1ms8/2T9wE3ZJRbz9bxEO7c0q1M= +github.com/raulk/go-watchdog v1.0.1/go.mod h1:lzSbAl5sh4rtI8tYHU01BWIDzgzqaQLj6RcA1i4mlqI= github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0 h1:OdAsTTz6OkFY5QxjkYwrChwuRruF69c169dPK26NUlk= github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo= github.com/rhysd/go-github-selfupdate v1.2.2 h1:G+mNzkc1wEtpmM6sFS/Ghkeq+ad4Yp6EZEHyp//wGEo= github.com/rhysd/go-github-selfupdate v1.2.2/go.mod h1:khesvSyKcXDUxeySCedFh621iawCks0dS/QnHPcpCws= +github.com/rivo/uniseg v0.1.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= +github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY= +github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= github.com/robfig/cron/v3 v3.0.1 h1:WdRxkvbJztn8LMz/QEvLN5sBU+xKpSqwwUO1Pjr4qDs= github.com/robfig/cron/v3 v3.0.1/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzGIFLtro= github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= @@ -1715,11 +1741,12 @@ github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5 github.com/stretchr/testify v1.6.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stripe/stripe-go/v72 v72.10.0 h1:4Rsv7Ts4D2qii2r0gW3qZpvPXRV0W8BpagLgvh7kRjY= github.com/stripe/stripe-go/v72 v72.10.0/go.mod h1:QwqJQtduHubZht9mek5sds9CtQcKFdsykV9ZepRWwo0= github.com/subosito/gotenv v1.2.0 h1:Slr1R9HxAlEKefgq5jn9U+DnETlIUa6HfgEzj0g5d7s= github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= -github.com/supranational/blst v0.1.1/go.mod h1:jZJtfjgudtNl4en1tzwPIV3KjUnQUvG3/j+w+fVonLw= github.com/syndtr/goleveldb v1.0.0 h1:fBdIW9lB4Iz0n9khmH8w27SJ3QEJ7+IgjPEwGSZiFdE= github.com/syndtr/goleveldb v1.0.0/go.mod h1:ZVVdQEZoIme9iO1Ch2Jdy24qqXrMMOU6lpPAyBWyWuQ= github.com/tarm/serial v0.0.0-20180830185346-98f6abe2eb07/go.mod h1:kDXzergiv9cbyO7IOYJZWg1U88JhDg3PB6klq9Hg2pA= @@ -1740,8 +1767,8 @@ github.com/textileio/go-ds-mongo v0.1.5-0.20201230201018-2b7fdca787a5 h1:wy2WAFw github.com/textileio/go-ds-mongo v0.1.5-0.20201230201018-2b7fdca787a5/go.mod h1:Zf6JlMPiIQUUmGlFFn5Z65C9p9LAvPg7XvX+qdGmTsU= github.com/textileio/go-threads v1.0.3-0.20201216032729-f7b034a0de80 h1:UJbiLtEmaRp9zUif+thvxsIOkeZnTECIWcaURCBaXS4= github.com/textileio/go-threads v1.0.3-0.20201216032729-f7b034a0de80/go.mod h1:kvIXqo4T4fS6fDyNeqRAIE5CXDguBXUi8kZVb4FGg0U= -github.com/textileio/powergate/v2 v2.0.0 h1:OqJLDyJUU46goa1D1M9RzuwYjDPre81ByDNWd9aGfU0= -github.com/textileio/powergate/v2 v2.0.0/go.mod h1:xC4R25o7VhnFsfNHOIGyK5Qsq/6xy2bZo2Q+uaf2ZtM= +github.com/textileio/powergate/v2 v2.1.1-0.20210226193238-217dae95e6e1 h1:W0AHqVgtPU0mGaWUAcm7p/1zxnmFjjsElEgTCjlQYsY= +github.com/textileio/powergate/v2 v2.1.1-0.20210226193238-217dae95e6e1/go.mod h1:2mZQwhHWbb4PLpy+zlUd6oZAOS84PtghwiCKrnsV9B8= github.com/texttheater/golang-levenshtein v0.0.0-20180516184445-d188e65d659e/go.mod h1:XDKHRm5ThF8YJjx001LtgelzsoaEcvnA7lVWz9EeX3g= github.com/tidwall/gjson v1.3.5 h1:2oW9FBNu8qt9jy5URgrzsVx/T/KSn3qn/smJQ0crlDQ= github.com/tidwall/gjson v1.3.5/go.mod h1:P256ACg0Mn+j1RXIDXoss50DeIABTYK1PULOJHhxOls= @@ -1769,6 +1796,7 @@ github.com/ulikunitz/xz v0.5.5 h1:pFrO0lVpTBXLpYw+pnLj6TbvHuyjXMfjGeCwSqCVwok= github.com/ulikunitz/xz v0.5.5/go.mod h1:2bypXElzHzzJZwzH67Y6wb67pO62Rzfn7BSiF4ABRW8= github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= +github.com/urfave/cli v1.22.2/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= github.com/urfave/cli v1.22.3 h1:FpNT6zq26xNpHZy08emi755QwzLPs6Pukqjlc7RfOMU= github.com/urfave/cli v1.22.3/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= github.com/urfave/cli/v2 v2.0.0/go.mod h1:SE9GqnLQmjVa0iPEY0f1w3ygNIYcIJ0OKPMoW2caLfQ= @@ -1802,6 +1830,8 @@ github.com/whyrusleeping/cbor-gen v0.0.0-20200810223238-211df3b9e24c/go.mod h1:f github.com/whyrusleeping/cbor-gen v0.0.0-20200812213548-958ddffe352c/go.mod h1:fgkXqYy7bV2cFeIEOkVTZS/WjXARfBqSH6Q2qHL33hQ= github.com/whyrusleeping/cbor-gen v0.0.0-20200826160007-0b9f6c5fb163 h1:TtcUeY2XZSriVWR1pXyfCBWIf/NGC2iUdNw1lofUjUU= github.com/whyrusleeping/cbor-gen v0.0.0-20200826160007-0b9f6c5fb163/go.mod h1:fgkXqYy7bV2cFeIEOkVTZS/WjXARfBqSH6Q2qHL33hQ= +github.com/whyrusleeping/cbor-gen v0.0.0-20210118024343-169e9d70c0c2 h1:7HzUKl5d/dELS9lLeT4W6YvliZx+s9k/eOOIdHKrA/w= +github.com/whyrusleeping/cbor-gen v0.0.0-20210118024343-169e9d70c0c2/go.mod h1:fgkXqYy7bV2cFeIEOkVTZS/WjXARfBqSH6Q2qHL33hQ= github.com/whyrusleeping/chunker v0.0.0-20181014151217-fe64bd25879f h1:jQa4QT2UP9WYv2nzyawpKMOCl+Z/jW7djv2/J50lj9E= github.com/whyrusleeping/chunker v0.0.0-20181014151217-fe64bd25879f/go.mod h1:p9UJB6dDgdPgMJZs7UjUOdulKyRr9fqkS+6JKAInPy8= github.com/whyrusleeping/go-ctrlnet v0.0.0-20180313164037-f564fbbdaa95/go.mod h1:SJqKCCPXRfBFCwXjfNT/skfsceF7+MBFLI2OrvuRA7g= @@ -1820,7 +1850,7 @@ github.com/whyrusleeping/mdns v0.0.0-20180901202407-ef14215e6b30/go.mod h1:j4l84 github.com/whyrusleeping/mdns v0.0.0-20190826153040-b9b60ed33aa9/go.mod h1:j4l84WPFclQPj320J9gp0XwNKBb3U0zt5CBqjPp22G4= github.com/whyrusleeping/multiaddr-filter v0.0.0-20160516205228-e903e4adabd7 h1:E9S12nwJwEOXe2d6gT6qxdvqMnNq+VnSsKPgm2ZZNds= github.com/whyrusleeping/multiaddr-filter v0.0.0-20160516205228-e903e4adabd7/go.mod h1:X2c0RVCI1eSUFI8eLcY3c0423ykwiUdxLJtkDvruhjI= -github.com/whyrusleeping/pubsub v0.0.0-20131020042734-02de8aa2db3d/go.mod h1:g7ckxrjiFh8mi1AY7ox23PZD0g6QU/TxW3U3unX7I3A= +github.com/whyrusleeping/pubsub v0.0.0-20190708150250-92bcb0691325/go.mod h1:g7ckxrjiFh8mi1AY7ox23PZD0g6QU/TxW3U3unX7I3A= github.com/whyrusleeping/timecache v0.0.0-20160911033111-cfcb2f1abfee h1:lYbXeSvJi5zk5GLKVuid9TVjS9a0OmLIDKTfoZBL6Ow= github.com/whyrusleeping/timecache v0.0.0-20160911033111-cfcb2f1abfee/go.mod h1:m2aV4LZI4Aez7dP5PMyVKEHhUyEJ/RjmPEDOpDvudHg= github.com/whyrusleeping/yamux v1.1.5/go.mod h1:E8LnQQ8HKx5KD29HZFUwM1PxCOdPRzGwur1mcYhXcD8= @@ -1881,6 +1911,8 @@ go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.5 h1:dntmOdLpSpHlVqbW5Eay97DelsZHe+55D+xC6i0dDS0= go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= +go.opencensus.io v0.22.6 h1:BdkrbWrzDlV9dnbzoP7sfN+dHheJ4J9JOaYxcUDL+ok= +go.opencensus.io v0.22.6/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= @@ -2032,6 +2064,8 @@ golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81R golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20201021035429-f5854403a974 h1:IX6qOQeG5uLjB/hjjwjedwfjND0hgjPMMyO1RoIXQNI= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20201110031124-69a78807bb2b h1:uwuIcX0g4Yl1NC5XAz37xsr2lTtcqevgzYNVt49waME= +golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181017192945-9dcd33a902f4/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181106182150-f42d05182288/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -2051,8 +2085,8 @@ golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9 h1:SQFwaSi55rU7vdNs9Yr0Z324VNlrF+0wMqRXT4St8ck= -golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20201207232520-09787c993a3a h1:DcqTD9SDLc+1P/r1EmRBwnVsrOwW+kk2vWf9n+1sGhs= +golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180202135801-37707fdb30a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180810173357-98c5dad5d1a0/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -2283,8 +2317,9 @@ google.golang.org/grpc v1.28.1/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKa google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= google.golang.org/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= -google.golang.org/grpc v1.34.0 h1:raiipEjMOIC/TO2AvyTxP25XFdLxNIBwzDh3FM3XztI= -google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8= +google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= +google.golang.org/grpc v1.35.0 h1:TwIQcH3es+MojMVojxxfQ3l3OF2KzlRxML2xZq0kRo8= +google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= google.golang.org/grpc/examples v0.0.0-20200819190100-f640ae6a4f43 h1:8VjjqQOg+UAkXgmUqmzpJqj0uUWLoJZNZlBiAK8YBsc= google.golang.org/grpc/examples v0.0.0-20200819190100-f640ae6a4f43/go.mod h1:wQWkdCkP0Pl3MzFPvfqTNUnXA2eIVY4eakDiKJvniKc= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= @@ -2304,6 +2339,8 @@ gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8 gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU= +gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw= gopkg.in/cheggaaa/pb.v1 v1.0.28/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= @@ -2352,7 +2389,6 @@ honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9 honnef.co/go/tools v0.0.1-2020.1.4 h1:UoveltGrhghAA7ePc+e+QYDHXrBps2PqFZiHkGR/xK8= honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= howett.net/plist v0.0.0-20181124034731-591f970eefbb/go.mod h1:vMygbs4qMhSZSc4lCUl2OEE+rDiIIJAIdR4m7MiMcm0= -launchpad.net/gocheck v0.0.0-20140225173054-000000000087/go.mod h1:hj7XX3B/0A+80Vse0e+BUHsHMTEhd0O4cpUHr/e/BUM= modernc.org/cc v1.0.0 h1:nPibNuDEx6tvYrUAtvDTTw98rx5juGsa5zuDnKwEEQQ= modernc.org/cc v1.0.0/go.mod h1:1Sk4//wdnYJiUIxnW8ddKpaOJCF37yAdqYnkxUpaYxw= modernc.org/golex v1.0.0 h1:wWpDlbK8ejRfSyi0frMyhilD3JBvtcx2AdGDnU+JtsE= From 15e82f5e6cf68ed39773e62dbea2ebac627a54e5 Mon Sep 17 00:00:00 2001 From: Aaron Sutula Date: Tue, 2 Mar 2021 15:28:48 -0600 Subject: [PATCH 04/16] make timeout and confidence configurable Signed-off-by: Aaron Sutula --- api/sendfild/service/service.go | 20 +++++++++++--------- api/sendfild/service/service_test.go | 12 +++++++----- 2 files changed, 18 insertions(+), 14 deletions(-) diff --git a/api/sendfild/service/service.go b/api/sendfild/service/service.go index 8bbdad679..824c186de 100644 --- a/api/sendfild/service/service.go +++ b/api/sendfild/service/service.go @@ -65,15 +65,18 @@ type Service struct { col *mongo.Collection server *grpc.Server waiting map[primitive.ObjectID]chan waitResult + config Config waitingLck sync.Mutex } type Config struct { - Listener net.Listener - ClientBuilder lotus.ClientBuilder - MongoUri string - MongoDbName string - Debug bool + Listener net.Listener + ClientBuilder lotus.ClientBuilder + MongoUri string + MongoDbName string + MessageWaitTimeout time.Duration + MessageConfidence uint64 + Debug bool } func New(ctx context.Context, config Config) (*Service, error) { @@ -128,6 +131,7 @@ func New(ctx context.Context, config Config) (*Service, error) { clientBuilder: config.ClientBuilder, col: col, waiting: make(map[primitive.ObjectID]chan waitResult), + config: config, } s.server = grpc.NewServer() @@ -487,8 +491,7 @@ func (s *Service) wait(tx txn) chan waitResult { s.waiting[tx.ID] = ch go func() { - // ToDo: make timeout configurable - ctx, cancel := context.WithTimeout(context.Background(), time.Minute*5) + ctx, cancel := context.WithTimeout(context.Background(), s.config.MessageWaitTimeout) client, closeClient, err := s.clientBuilder(ctx) defer func() { @@ -532,8 +535,7 @@ func (s *Service) wait(tx txn) chan waitResult { return } - // ToDo: Make confidence configurable - res, err := client.StateWaitMsg(ctx, c, 3) + res, err := client.StateWaitMsg(ctx, c, s.config.MessageConfidence) tx.Waiting = false if err != nil { if err := s.updateTxn(ctx, tx); err != nil { diff --git a/api/sendfild/service/service_test.go b/api/sendfild/service/service_test.go index 92894e504..f3e6237d8 100644 --- a/api/sendfild/service/service_test.go +++ b/api/sendfild/service/service_test.go @@ -481,11 +481,13 @@ func requireSetup(t *testing.T, ctx context.Context, speed int) (pb.SendFilServi listener := bufconn.Listen(bufSize) conf := Config{ - Listener: listener, - ClientBuilder: clientBuilder, - MongoUri: test.GetMongoUri(), - MongoDbName: util.MakeToken(12), - Debug: true, + Listener: listener, + ClientBuilder: clientBuilder, + MongoUri: test.GetMongoUri(), + MongoDbName: util.MakeToken(12), + MessageWaitTimeout: time.Minute, + MessageConfidence: 2, + Debug: true, } s, err := New(ctx, conf) require.NoError(t, err) From 1b0aea5b90df60ee43da79a0829f368b0ae68257 Mon Sep 17 00:00:00 2001 From: Aaron Sutula Date: Tue, 2 Mar 2021 17:13:03 -0600 Subject: [PATCH 05/16] client code Signed-off-by: Aaron Sutula --- api/sendfild/client/client.go | 199 +++++++++++++++++++++++++++ api/sendfild/service/service_test.go | 13 ++ 2 files changed, 212 insertions(+) create mode 100644 api/sendfild/client/client.go diff --git a/api/sendfild/client/client.go b/api/sendfild/client/client.go new file mode 100644 index 000000000..fa30334d2 --- /dev/null +++ b/api/sendfild/client/client.go @@ -0,0 +1,199 @@ +package client + +import ( + "context" + "fmt" + "time" + + "github.com/textileio/textile/v2/api/sendfild/pb" + "google.golang.org/grpc" + "google.golang.org/protobuf/types/known/timestamppb" +) + +type Client struct { + c pb.SendFilServiceClient + conn *grpc.ClientConn +} + +func New(target string, opts ...grpc.DialOption) (*Client, error) { + conn, err := grpc.Dial(target, opts...) + if err != nil { + return nil, fmt.Errorf("creating gRPC client conn: %v", err) + } + + c := pb.NewSendFilServiceClient(conn) + + return &Client{ + c: c, + conn: conn, + }, nil +} + +type SendFilOption = func(*pb.SendFilRequest) + +func SendFilWait() SendFilOption { + return func(req *pb.SendFilRequest) { + req.Wait = true + } +} + +func (c *Client) SendFil(ctx context.Context, from, to string, amountNanoFil int64, opts ...SendFilOption) (*pb.Txn, error) { + req := &pb.SendFilRequest{ + From: from, + To: to, + AmountNanoFil: amountNanoFil, + } + for _, opt := range opts { + opt(req) + } + res, err := c.c.SendFil(ctx, req) + if err != nil { + return nil, err + } + return res.Txn, nil +} + +type TxnOption = func(*pb.TxnRequest) + +func TxnWait() TxnOption { + return func(req *pb.TxnRequest) { + req.Wait = true + } +} + +func (c *Client) Txn(ctx context.Context, messageCid string, opts ...TxnOption) (*pb.Txn, error) { + req := &pb.TxnRequest{ + MessageCid: messageCid, + } + for _, opt := range opts { + opt(req) + } + res, err := c.c.Txn(ctx, req) + if err != nil { + return nil, err + } + return res.Txn, nil +} + +type ListTxnsOption = func(*pb.ListTxnsRequest) + +func ListTxnsFrom(from string) ListTxnsOption { + return func(req *pb.ListTxnsRequest) { + req.FromFilter = from + } +} + +func ListTxnsTo(to string) ListTxnsOption { + return func(req *pb.ListTxnsRequest) { + req.ToFilter = to + } +} + +func ListTxnsInvolving(involving string) ListTxnsOption { + return func(req *pb.ListTxnsRequest) { + req.InvolvingFilter = involving + } +} + +func ListTxnsAmountNanoFilLt(amountNanoFil int64) ListTxnsOption { + return func(req *pb.ListTxnsRequest) { + req.AmountNanoFilLtFilter = amountNanoFil + } +} + +func ListTxnsAmountNanoFilGt(amountNanoFil int64) ListTxnsOption { + return func(req *pb.ListTxnsRequest) { + req.AmountNanoFilGtFilter = amountNanoFil + } +} + +func ListTxnsAmountNanoFilLteq(amountNanoFil int64) ListTxnsOption { + return func(req *pb.ListTxnsRequest) { + req.AmountNanoFilLteqFilter = amountNanoFil + } +} + +func ListTxnsAmountNanoFilGteq(amountNanoFil int64) ListTxnsOption { + return func(req *pb.ListTxnsRequest) { + req.AmountNanoFilGteqFilter = amountNanoFil + } +} + +func ListTxnsAmountNanoFilEq(amountNanoFil int64) ListTxnsOption { + return func(req *pb.ListTxnsRequest) { + req.AmountNanoFilEqFilter = amountNanoFil + } +} + +func ListTxnsMessageState(messageState pb.MessageState) ListTxnsOption { + return func(req *pb.ListTxnsRequest) { + req.MessageStateFilter = messageState + } +} + +func ListTxnsWaiting(waitingFilter pb.WaitingFilter) ListTxnsOption { + return func(req *pb.ListTxnsRequest) { + req.WaitingFilter = waitingFilter + } +} + +func ListTxnsCreatedAfter(time time.Time) ListTxnsOption { + return func(req *pb.ListTxnsRequest) { + req.CreatedAfter = timestamppb.New(time) + } +} + +func ListTxnsCreatedBefore(time time.Time) ListTxnsOption { + return func(req *pb.ListTxnsRequest) { + req.CreatedBefore = timestamppb.New(time) + } +} + +func ListTxnsUpdatedAfter(time time.Time) ListTxnsOption { + return func(req *pb.ListTxnsRequest) { + req.UpdatedAfter = timestamppb.New(time) + } +} + +func ListTxnsUpdatedBefore(time time.Time) ListTxnsOption { + return func(req *pb.ListTxnsRequest) { + req.UpdatedBefore = timestamppb.New(time) + } +} + +func ListTxnsAscending() ListTxnsOption { + return func(req *pb.ListTxnsRequest) { + req.Ascending = true + } +} + +func ListTxnsMoreToken(moreToken int64) ListTxnsOption { + return func(req *pb.ListTxnsRequest) { + req.MoreToken = moreToken + } +} + +func ListTxnsLimit(limit int64) ListTxnsOption { + return func(req *pb.ListTxnsRequest) { + req.Limit = limit + } +} + +func (c *Client) ListTxns(ctx context.Context, opts ...ListTxnsOption) ([]*pb.Txn, bool, int64, error) { + req := &pb.ListTxnsRequest{} + for _, opt := range opts { + opt(req) + } + res, err := c.c.ListTxns(ctx, req) + if err != nil { + return nil, false, 0, err + } + return res.Txns, res.More, res.MoreToken, nil +} + +func (c *Client) Close() error { + if c == nil { + return nil + } + return c.conn.Close() +} diff --git a/api/sendfild/service/service_test.go b/api/sendfild/service/service_test.go index f3e6237d8..28bf7b185 100644 --- a/api/sendfild/service/service_test.go +++ b/api/sendfild/service/service_test.go @@ -269,6 +269,19 @@ func TestListTxnsAmtGtLteq(t *testing.T) { require.Len(t, res.Txns, 1) } +func TestListTxnsAmtEq(t *testing.T) { + c, lc, dAddr, cleanup := requireSetup(t, ctx, 300) + defer cleanup() + addr1 := requireLotusAddress(t, ctx, lc) + requireSendFil(t, ctx, c, dAddr.String(), addr1.String(), oneFil/2, false) + requireSendFil(t, ctx, c, dAddr.String(), addr1.String(), oneFil, false) + requireSendFil(t, ctx, c, dAddr.String(), addr1.String(), oneFil*2, false) + requireSendFil(t, ctx, c, dAddr.String(), addr1.String(), oneFil*3, false) + res, err := c.ListTxns(ctx, &pb.ListTxnsRequest{AmountNanoFilEqFilter: oneFil}) + require.NoError(t, err) + require.Len(t, res.Txns, 1) +} + func TestListTxnsMessageState(t *testing.T) { c, lc, dAddr, cleanup := requireSetup(t, ctx, 1000) defer cleanup() From 10cb87d1c46c2090423a56cb88418a9c83c49ff6 Mon Sep 17 00:00:00 2001 From: Aaron Sutula Date: Tue, 2 Mar 2021 18:43:42 -0600 Subject: [PATCH 06/16] executable and docker config and makefile updates Signed-off-by: Aaron Sutula --- Makefile | 8 ++ api/sendfild/Dockerfile | 74 +++++++++++++ api/sendfild/Dockerfile.dev | 36 +++++++ api/sendfild/main.go | 202 ++++++++++++++++++++++++++++++++++++ go.mod | 10 +- go.sum | 32 +++--- 6 files changed, 345 insertions(+), 17 deletions(-) create mode 100644 api/sendfild/Dockerfile create mode 100644 api/sendfild/Dockerfile.dev create mode 100644 api/sendfild/main.go diff --git a/Makefile b/Makefile index d82838f80..439be0fe2 100644 --- a/Makefile +++ b/Makefile @@ -38,6 +38,10 @@ build-filrewardsd: $(GOVVV) $(TXTL_BUILD_FLAGS) go build -ldflags="${GOVVV_FLAGS}" ./api/filrewardsd .PHONY: build-filrewardsd +build-sendfild: $(GOVVV) + $(TXTL_BUILD_FLAGS) go build -ldflags="${GOVVV_FLAGS}" ./api/sendfild +.PHONY: build-sendfild + install: $(GOVVV) $(TXTL_BUILD_FLAGS) go install -ldflags="${GOVVV_FLAGS}" ./... .PHONY: install @@ -70,6 +74,10 @@ install-filrewardsd: $(GOVVV) $(TXTL_BUILD_FLAGS) go install -ldflags="${GOVVV_FLAGS}" ./api/filrewardsd .PHONY: install-filrewardsd +install-sendfild: $(GOVVV) + $(TXTL_BUILD_FLAGS) go install -ldflags="${GOVVV_FLAGS}" ./api/sendfild +.PHONY: install-sendfild + define gen_release_files $(GOX) -osarch=$(3) -output="build/$(2)/$(2)_${TXTL_VERSION}_{{.OS}}-{{.Arch}}/$(2)" -ldflags="${GOVVV_FLAGS}" $(1) mkdir -p build/dist; \ diff --git a/api/sendfild/Dockerfile b/api/sendfild/Dockerfile new file mode 100644 index 000000000..b81a803bb --- /dev/null +++ b/api/sendfild/Dockerfile @@ -0,0 +1,74 @@ +FROM golang:1.15.5-buster +MAINTAINER Textile + +# This is (in large part) copied (with love) from +# https://hub.docker.com/r/ipfs/go-ipfs/dockerfile + +# Install deps +RUN apt-get update && apt-get install -y \ + libssl-dev \ + ca-certificates + +ENV SRC_DIR /textile + +# Download packages first so they can be cached. +COPY go.mod go.sum $SRC_DIR/ +RUN cd $SRC_DIR \ + && go mod download + +COPY . $SRC_DIR + +# Build the thing. +RUN cd $SRC_DIR \ + && TXTL_BUILD_FLAGS="CGO_ENABLED=0 GOOS=linux" make build-sendfild + +# Get su-exec, a very minimal tool for dropping privileges, +# and tini, a very minimal init daemon for containers +ENV SUEXEC_VERSION v0.2 +ENV TINI_VERSION v0.19.0 +RUN set -eux; \ + dpkgArch="$(dpkg --print-architecture)"; \ + case "${dpkgArch##*-}" in \ + "amd64" | "armhf" | "arm64") tiniArch="tini-static-$dpkgArch" ;;\ + *) echo >&2 "unsupported architecture: ${dpkgArch}"; exit 1 ;; \ + esac; \ + cd /tmp \ + && git clone https://github.com/ncopa/su-exec.git \ + && cd su-exec \ + && git checkout -q $SUEXEC_VERSION \ + && make su-exec-static \ + && cd /tmp \ + && wget -q -O tini https://github.com/krallin/tini/releases/download/$TINI_VERSION/$tiniArch \ + && chmod +x tini + +# Now comes the actual target image, which aims to be as small as possible. +FROM busybox:1.31.1-glibc +LABEL maintainer="Textile " + +# Get the textile binary, entrypoint script, and TLS CAs from the build container. +ENV SRC_DIR /textile +COPY --from=0 $SRC_DIR/sendfild /usr/local/bin/sendfild +COPY --from=0 /tmp/su-exec/su-exec-static /sbin/su-exec +COPY --from=0 /tmp/tini /sbin/tini +COPY --from=0 /etc/ssl/certs /etc/ssl/certs + +# This shared lib (part of glibc) doesn't seem to be included with busybox. +COPY --from=0 /lib/*-linux-gnu*/libdl.so.2 /lib/ + +# Copy over SSL libraries. +COPY --from=0 /usr/lib/*-linux-gnu*/libssl.so* /usr/lib/ +COPY --from=0 /usr/lib/*-linux-gnu*/libcrypto.so* /usr/lib/ + +# listenAddrs +EXPOSE 7006 + +# Create the repo directory. +ENV SENDFIL_PATH /data/sendfil +RUN mkdir -p $SENDFIL_PATH \ + && adduser -D -h $SENDFIL_PATH -u 1000 -G users sendfil \ + && chown sendfil:users $SENDFIL_PATH + +# Switch to a non-privileged user. +USER sendfil + +ENTRYPOINT ["/sbin/tini", "--", "sendfild"] diff --git a/api/sendfild/Dockerfile.dev b/api/sendfild/Dockerfile.dev new file mode 100644 index 000000000..eee185310 --- /dev/null +++ b/api/sendfild/Dockerfile.dev @@ -0,0 +1,36 @@ +FROM golang:1.15.5-buster + +RUN apt-get update && apt-get install -y \ + libssl-dev \ + ca-certificates + +RUN go get github.com/go-delve/delve/cmd/dlv + +ENV SRC_DIR /textile + +COPY go.mod go.sum $SRC_DIR/ +RUN cd $SRC_DIR \ + && go mod download + +COPY . $SRC_DIR + +RUN cd $SRC_DIR \ + && CGO_ENABLED=0 GOOS=linux go build -gcflags "all=-N -l" -o sendfild api/sendfild/main.go + +FROM debian:buster +LABEL maintainer="Textile " + +ENV SRC_DIR /textile +COPY --from=0 /go/bin/dlv /usr/local/bin/dlv +COPY --from=0 /etc/ssl/certs /etc/ssl/certs +COPY --from=0 $SRC_DIR/sendfild /usr/local/bin/sendfild + +EXPOSE 10006 +EXPOSE 8010 + +ENV SENDFIL_PATH /data/sendfil +RUN adduser --home $SENDFIL_PATH --disabled-login --gecos "" --ingroup users sendfil + +USER sendfil + +ENTRYPOINT ["dlv", "--listen=0.0.0.0:40000", "--headless=true", "--accept-multiclient", "--continue", "--api-version=2", "exec", "/usr/local/bin/sendfild"] diff --git a/api/sendfild/main.go b/api/sendfild/main.go new file mode 100644 index 000000000..6379cdfa6 --- /dev/null +++ b/api/sendfild/main.go @@ -0,0 +1,202 @@ +package main + +import ( + "context" + "encoding/json" + "fmt" + "net" + "time" + + logging "github.com/ipfs/go-log/v2" + "github.com/spf13/cobra" + "github.com/spf13/viper" + "github.com/textileio/go-threads/util" + "github.com/textileio/powergate/v2/lotus" + "github.com/textileio/textile/v2/api/sendfild/service" + "github.com/textileio/textile/v2/cmd" +) + +const daemonName = "sendfild" + +var ( + log = logging.Logger(daemonName) + + config = &cmd.Config{ + Viper: viper.New(), + Dir: "." + daemonName, + Name: "config", + Flags: map[string]cmd.Flag{ + "debug": { + Key: "debug", + DefValue: false, + }, + "logFile": { + Key: "log_file", + DefValue: "", // no log file + }, + "listenAddr": { + Key: "listen_addr", + DefValue: "127.0.0.1:5000", + }, + "lotusAddr": { + Key: "lotus_addr", + DefValue: "127.0.0.1:7777", + }, + "lotusAuthToken": { + Key: "lotus_auth_token", + DefValue: "", + }, + "lotusConnRetries": { + Key: "lotus_conn_retries", + DefValue: 2, + }, + "mongoUri": { + Key: "mongo_uri", + DefValue: "mongodb://127.0.0.1:27017", + }, + "mongoDb": { + Key: "mongo_db", + DefValue: "textile_sendfil", + }, + "messageWaitTimeout": { + Key: "message_wait_timeout", + DefValue: time.Minute * 5, + }, + "messageConfidence": { + Key: "message_confidence", + DefValue: uint64(2), + }, + }, + EnvPre: "SENDFIL", + Global: true, + } +) + +func init() { + cobra.OnInitialize(cmd.InitConfig(config)) + cmd.InitConfigCmd(rootCmd, config.Viper, config.Dir) + + rootCmd.PersistentFlags().StringVar( + &config.File, + "config", + "", + "Config file (default ${HOME}/"+config.Dir+"/"+config.Name+".yml)") + rootCmd.PersistentFlags().BoolP( + "debug", + "d", + config.Flags["debug"].DefValue.(bool), + "Enable debug logging") + rootCmd.PersistentFlags().String( + "logFile", + config.Flags["logFile"].DefValue.(string), + "Write logs to file") + + rootCmd.PersistentFlags().String( + "listenAddr", + config.Flags["listenAddr"].DefValue.(string), + "Sendfil API listen address") + + rootCmd.PersistentFlags().String( + "lotusAddr", + config.Flags["lotusAddr"].DefValue.(string), + "Lotus API address") + rootCmd.PersistentFlags().String( + "lotusAuthToken", + config.Flags["lotusAuthToken"].DefValue.(string), + "Lotus API auth token") + rootCmd.PersistentFlags().Int( + "lotusConnRetries", + config.Flags["lotusConnRetries"].DefValue.(int), + "Lotus API connection retry count") + + rootCmd.PersistentFlags().String( + "mongoUri", + config.Flags["mongoUri"].DefValue.(string), + "MongoDB connection URI") + rootCmd.PersistentFlags().String( + "mongoDb", + config.Flags["mongoDb"].DefValue.(string), + "MongoDB database name") + + rootCmd.PersistentFlags().Duration( + "messageWaitTimeout", + config.Flags["messageWaitTimeout"].DefValue.(time.Duration), + "Timeout for listening for messages to become active on chain") + + rootCmd.PersistentFlags().Int64( + "messageConfidence", + config.Flags["messageConfidence"].DefValue.(int64), + "Confidence, in epochs, used to consider a message active on chain", + ) + + err := cmd.BindFlags(config.Viper, rootCmd, config.Flags) + cmd.ErrCheck(err) +} + +func main() { + cmd.ErrCheck(rootCmd.Execute()) +} + +var rootCmd = &cobra.Command{ + Use: daemonName, + Short: "Sendfil daemon", + Long: `Textile's sendfil daemon.`, + PersistentPreRun: func(c *cobra.Command, args []string) { + config.Viper.SetConfigType("yaml") + cmd.ExpandConfigVars(config.Viper, config.Flags) + + if config.Viper.GetBool("debug") { + err := util.SetLogLevels(map[string]logging.LogLevel{ + daemonName: logging.LevelDebug, + }) + cmd.ErrCheck(err) + } + }, + Run: func(c *cobra.Command, args []string) { + settings, err := json.MarshalIndent(config.Viper.AllSettings(), "", " ") + cmd.ErrCheck(err) + log.Debugf("loaded config: %s", string(settings)) + + debug := config.Viper.GetBool("debug") + logFile := config.Viper.GetString("log_file") + listenAddr := config.Viper.GetString("listen_addr") + lotusAddr := config.Viper.GetString("lotus_addr") + lotusAuthToken := config.Viper.GetString("lotus_auth_token") + lotusConnRetries := config.Viper.GetInt("lotus_conn_retries") + mongoUri := config.Viper.GetString("mongo_uri") + mongoDb := config.Viper.GetString("mongo_db") + messageTimeout := config.Viper.GetDuration("message_timeout") + messageConfidence := config.Viper.GetInt64("message_confidence") + + if logFile != "" { + err = cmd.SetupDefaultLoggingConfig(logFile) + cmd.ErrCheck(err) + } + + listener, err := net.Listen("tcp", listenAddr) + cmd.ErrCheck(err) + + cb, err := lotus.NewBuilder(lotusAddr, lotusAuthToken, lotusConnRetries) + cmd.ErrCheck(err) + + ctx, cancel := context.WithCancel(context.Background()) + conf := service.Config{ + Listener: listener, + ClientBuilder: cb, + MongoUri: mongoUri, + MongoDbName: mongoDb, + MessageWaitTimeout: messageTimeout, + MessageConfidence: uint64(messageConfidence), + Debug: debug, + } + api, err := service.New(ctx, conf) + cmd.ErrCheck(err) + + fmt.Println("Welcome to Hub Sendfil!") + + cmd.HandleInterrupt(func() { + api.Close() + cancel() + }) + }, +} diff --git a/go.mod b/go.mod index 3f55a357f..076b681dd 100644 --- a/go.mod +++ b/go.mod @@ -14,8 +14,8 @@ require ( github.com/customerio/go-customerio v2.0.0+incompatible github.com/dgrijalva/jwt-go v3.2.0+incompatible github.com/filecoin-project/go-address v0.0.5 - github.com/filecoin-project/go-fil-markets v1.1.7 - github.com/filecoin-project/lotus v1.4.2 + github.com/filecoin-project/go-fil-markets v1.1.9 + github.com/filecoin-project/lotus v1.5.0 github.com/gin-contrib/location v0.0.2 github.com/gin-contrib/static v0.0.0-20191128031702-f81c604d8ac2 github.com/gin-gonic/gin v1.6.3 @@ -53,7 +53,7 @@ require ( github.com/multiformats/go-multibase v0.0.3 github.com/multiformats/go-multihash v0.0.14 github.com/oklog/ulid/v2 v2.0.2 - github.com/olekukonko/tablewriter v0.0.4 + github.com/olekukonko/tablewriter v0.0.5 github.com/pelletier/go-toml v1.7.0 // indirect github.com/phayes/freeport v0.0.0-20180830031419-95f893ade6f2 github.com/radovskyb/watcher v1.0.7 @@ -64,7 +64,7 @@ require ( github.com/segmentio/backo-go v0.0.0-20200129164019-23eae7c10bd3 // indirect github.com/spf13/afero v1.2.2 // indirect github.com/spf13/cast v1.3.1 // indirect - github.com/spf13/cobra v1.1.1 + github.com/spf13/cobra v1.1.3 github.com/spf13/jwalterweatherman v1.1.0 // indirect github.com/spf13/viper v1.7.1 github.com/stretchr/objx v0.2.0 // indirect @@ -74,7 +74,7 @@ require ( github.com/textileio/go-assets v0.0.0-20200430191519-b341e634e2b7 github.com/textileio/go-ds-mongo v0.1.5-0.20201230201018-2b7fdca787a5 github.com/textileio/go-threads v1.0.3-0.20201216032729-f7b034a0de80 - github.com/textileio/powergate/v2 v2.1.1-0.20210226193238-217dae95e6e1 + github.com/textileio/powergate/v2 v2.2.1-0.20210303000513-0d6f65779af2 github.com/xakep666/mongo-migrate v0.2.1 github.com/xtgo/uuid v0.0.0-20140804021211-a0b114877d4c // indirect go.mongodb.org/mongo-driver v1.4.1 diff --git a/go.sum b/go.sum index 03ee1b53c..391b3e1d2 100644 --- a/go.sum +++ b/go.sum @@ -328,8 +328,8 @@ github.com/filecoin-project/go-fil-commcid v0.0.0-20200716160307-8f644712406f/go github.com/filecoin-project/go-fil-commcid v0.0.0-20201016201715-d41df56b4f6a h1:hyJ+pUm/4U4RdEZBlg6k8Ma4rDiuvqyGpoICXAxwsTg= github.com/filecoin-project/go-fil-commcid v0.0.0-20201016201715-d41df56b4f6a/go.mod h1:Eaox7Hvus1JgPrL5+M3+h7aSPHc0cVqpSxA+TxIEpZQ= github.com/filecoin-project/go-fil-markets v1.0.5-0.20201113164554-c5eba40d5335/go.mod h1:AJySOJC00JRWEZzRG2KsfUnqEf5ITXxeX09BE9N4f9c= -github.com/filecoin-project/go-fil-markets v1.1.7 h1:7yy7alIDWzUxljxZhGmG3+wvaU4Ty5QDMbPmdZeaIJ8= -github.com/filecoin-project/go-fil-markets v1.1.7/go.mod h1:6oTRaAsHnCqhi3mpZqdvnWIzH6QzHQc4dbhJrI9/BfQ= +github.com/filecoin-project/go-fil-markets v1.1.9 h1:sA0NIEOpy7brZaeXeNgdXg5pvHaBtD5OTRlraOUbI0w= +github.com/filecoin-project/go-fil-markets v1.1.9/go.mod h1:0yQu5gvrjFoAIyzPSSJ+xUdCG83vjInAFbTswIB5/hk= github.com/filecoin-project/go-hamt-ipld v0.1.5 h1:uoXrKbCQZ49OHpsTCkrThPNelC4W3LPEk0OrS/ytIBM= github.com/filecoin-project/go-hamt-ipld v0.1.5/go.mod h1:6Is+ONR5Cd5R6XZoCse1CWaXZc0Hdb/JeX+EQCQzX24= github.com/filecoin-project/go-hamt-ipld/v2 v2.0.0 h1:b3UDemBYN2HNfk3KOXNuxgTTxlWi3xVvbQP0IT38fvM= @@ -349,16 +349,16 @@ github.com/filecoin-project/go-state-types v0.0.0-20200904021452-1883f36ca2f4/go github.com/filecoin-project/go-state-types v0.0.0-20200928172055-2df22083d8ab/go.mod h1:ezYnPf0bNkTsDibL/psSz5dy4B5awOJ/E7P2Saeep8g= github.com/filecoin-project/go-state-types v0.0.0-20201102161440-c8033295a1fc h1:+hbMY4Pcx2oizrfH08VWXwrj5mU8aJT6g0UNxGHFCGU= github.com/filecoin-project/go-state-types v0.0.0-20201102161440-c8033295a1fc/go.mod h1:ezYnPf0bNkTsDibL/psSz5dy4B5awOJ/E7P2Saeep8g= -github.com/filecoin-project/go-state-types v0.0.0-20210119062722-4adba5aaea71 h1:Cas/CUB4ybYpdxvW7LouaydE16cpwdq3vvS3qgZuU+Q= -github.com/filecoin-project/go-state-types v0.0.0-20210119062722-4adba5aaea71/go.mod h1:ezYnPf0bNkTsDibL/psSz5dy4B5awOJ/E7P2Saeep8g= +github.com/filecoin-project/go-state-types v0.1.0 h1:9r2HCSMMCmyMfGyMKxQtv0GKp6VT/m5GgVk8EhYbLJU= +github.com/filecoin-project/go-state-types v0.1.0/go.mod h1:ezYnPf0bNkTsDibL/psSz5dy4B5awOJ/E7P2Saeep8g= github.com/filecoin-project/go-statemachine v0.0.0-20200925024713-05bd7c71fbfe h1:dF8u+LEWeIcTcfUcCf3WFVlc81Fr2JKg8zPzIbBDKDw= github.com/filecoin-project/go-statemachine v0.0.0-20200925024713-05bd7c71fbfe/go.mod h1:FGwQgZAt2Gh5mjlwJUlVB62JeYdo+if0xWxSEfBD9ig= github.com/filecoin-project/go-statestore v0.1.0 h1:t56reH59843TwXHkMcwyuayStBIiWBRilQjQ+5IiwdQ= github.com/filecoin-project/go-statestore v0.1.0/go.mod h1:LFc9hD+fRxPqiHiaqUEZOinUJB4WARkRfNl10O7kTnI= github.com/filecoin-project/go-storedcounter v0.0.0-20200421200003-1c99c62e8a5b h1:fkRZSPrYpk42PV3/lIXiL0LHetxde7vyYYvSsttQtfg= github.com/filecoin-project/go-storedcounter v0.0.0-20200421200003-1c99c62e8a5b/go.mod h1:Q0GQOBtKf1oE10eSXSlhN45kDBdGvEcVOqMiffqX+N8= -github.com/filecoin-project/lotus v1.4.2 h1:s7cncb881O9c4uWVU4bjJpQY/ANtuGiKUFTgI00LxuI= -github.com/filecoin-project/lotus v1.4.2/go.mod h1:+tmCnqmSGrJp5CNyuXai1CCAFRKj50HKaKrpy2S/X5c= +github.com/filecoin-project/lotus v1.5.0 h1:LE6lALwXyvzNpo1rDXxxfy2NPNT7K54stwg1/kA2yXg= +github.com/filecoin-project/lotus v1.5.0/go.mod h1:Xi7fm05RL76CBYgyXnmWXULPvoGLya9gvM4sUYgIY1o= github.com/filecoin-project/specs-actors v0.6.1/go.mod h1:dRdy3cURykh2R8O/DKqy8olScl70rmIS7GrB4hB1IDY= github.com/filecoin-project/specs-actors v0.9.4/go.mod h1:BStZQzx5x7TmCkLv0Bpa07U6cPKol6fd3w9KjMPZ6Z4= github.com/filecoin-project/specs-actors v0.9.12 h1:iIvk58tuMtmloFNHhAOQHG+4Gci6Lui0n7DYQGi3cJk= @@ -370,8 +370,8 @@ github.com/filecoin-project/specs-actors/v2 v2.3.2 h1:2Vcf4CGa29kRh4JJ02m+FbvD/p github.com/filecoin-project/specs-actors/v2 v2.3.2/go.mod h1:UuJQLoTx/HPvvWeqlIFmC/ywlOLHNe8SNQ3OunFbu2Y= github.com/filecoin-project/specs-actors/v2 v2.3.4 h1:NZK2oMCcA71wNsUzDBmLQyRMzcCnX9tDGvwZ53G67j8= github.com/filecoin-project/specs-actors/v2 v2.3.4/go.mod h1:UuJQLoTx/HPvvWeqlIFmC/ywlOLHNe8SNQ3OunFbu2Y= -github.com/filecoin-project/specs-actors/v3 v3.0.1-0.20210128235937-57195d8909b1 h1:I6mvbwANIoToUZ37cYmuLyDKbPlAUxWnp0fJOZnlTz4= -github.com/filecoin-project/specs-actors/v3 v3.0.1-0.20210128235937-57195d8909b1/go.mod h1:NL24TPjJGyU7fh1ztpUyYcoZi3TmRKNEI0huPYmhObA= +github.com/filecoin-project/specs-actors/v3 v3.0.3 h1:bq9B1Jnq+Z0A+Yj3KnYhN3kcTpUyP6Umo3MZgai0BRE= +github.com/filecoin-project/specs-actors/v3 v3.0.3/go.mod h1:oMcmEed6B7H/wHabM3RQphTIhq0ibAKsbpYs+bQ/uxQ= github.com/filecoin-project/specs-storage v0.1.1-0.20201105051918-5188d9774506 h1:Ur/l2+6qN+lQiqjozWWc5p9UDaAMDZKTlDS98oRnlIw= github.com/filecoin-project/specs-storage v0.1.1-0.20201105051918-5188d9774506/go.mod h1:nJRRM7Aa9XVvygr3W9k6xGF46RWzr2zxF/iGoAIfA/g= github.com/filecoin-project/test-vectors/schema v0.0.5/go.mod h1:iQ9QXLpYWL3m7warwvK1JC/pTri8mnfEmKygNDqqY6E= @@ -649,6 +649,8 @@ github.com/ipfs/go-bitswap v0.3.3/go.mod h1:AyWWfN3moBzQX0banEtfKOfbXb3ZeoOeXnZG github.com/ipfs/go-block-format v0.0.1/go.mod h1:DK/YYcsSUIVAFNwo/KZCdIIbpN0ROH/baNLgayt4pFc= github.com/ipfs/go-block-format v0.0.2 h1:qPDvcP19izTjU8rgo6p7gTXZlkMkF5bz5G3fqIsSCPE= github.com/ipfs/go-block-format v0.0.2/go.mod h1:AWR46JfpcObNfg3ok2JHDUfdiHRgWhJgCQF+KIgOPJY= +github.com/ipfs/go-block-format v0.0.3 h1:r8t66QstRp/pd/or4dpnbVfXT5Gt7lOqRvC+/dDTpMc= +github.com/ipfs/go-block-format v0.0.3/go.mod h1:4LmD4ZUw0mhO+JSKdpWwrzATiEfM7WWgQ8H5l6P8MVk= github.com/ipfs/go-blockservice v0.0.3/go.mod h1:/NNihwTi6V2Yr6g8wBI+BSwPuURpBRMtYNGrlxZ8KuI= github.com/ipfs/go-blockservice v0.0.7/go.mod h1:EOfb9k/Y878ZTRY/CH0x5+ATtaipfbRhbvNSdgc/7So= github.com/ipfs/go-blockservice v0.1.0/go.mod h1:hzmMScl1kXHg3M2BjTymbVPjv627N7sYcvYaKbop39M= @@ -1474,6 +1476,8 @@ github.com/oklog/ulid/v2 v2.0.2/go.mod h1:mtBL0Qe/0HAx6/a4Z30qxVIAL1eQDweXq5lxOE github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= github.com/olekukonko/tablewriter v0.0.4 h1:vHD/YYe1Wolo78koG299f7V/VAS08c6IpCLn+Ejf/w8= github.com/olekukonko/tablewriter v0.0.4/go.mod h1:zq6QwlOf5SlnkVbMSr5EoBv3636FWnp+qbPhuoO21uA= +github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec= +github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.8.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= @@ -1709,8 +1713,8 @@ github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkU github.com/spf13/cobra v0.0.2-0.20171109065643-2da4a54c5cee/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU= -github.com/spf13/cobra v1.1.1 h1:KfztREH0tPxJJ+geloSLaAkaPkr4ki2Er5quFV1TDo4= -github.com/spf13/cobra v1.1.1/go.mod h1:WnodtKOvamDL/PwE2M4iKs8aMDBZ5Q5klgD3qfVJQMI= +github.com/spf13/cobra v1.1.3 h1:xghbfqPkxzxP3C/f3n5DdpAbdKLj4ZE4BWQI362l53M= +github.com/spf13/cobra v1.1.3/go.mod h1:pGADOWyqRD/YMrPZigI/zbliZ2wVD/23d+is3pSWzOo= github.com/spf13/jwalterweatherman v1.0.0 h1:XHEdyB+EcvlqZamSM4ZOMGlc93t6AcsBEu9Gc1vn7yk= github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= github.com/spf13/jwalterweatherman v1.1.0 h1:ue6voC5bR5F8YxI5S67j9i582FU4Qvo2bmqnqMYADFk= @@ -1767,8 +1771,8 @@ github.com/textileio/go-ds-mongo v0.1.5-0.20201230201018-2b7fdca787a5 h1:wy2WAFw github.com/textileio/go-ds-mongo v0.1.5-0.20201230201018-2b7fdca787a5/go.mod h1:Zf6JlMPiIQUUmGlFFn5Z65C9p9LAvPg7XvX+qdGmTsU= github.com/textileio/go-threads v1.0.3-0.20201216032729-f7b034a0de80 h1:UJbiLtEmaRp9zUif+thvxsIOkeZnTECIWcaURCBaXS4= github.com/textileio/go-threads v1.0.3-0.20201216032729-f7b034a0de80/go.mod h1:kvIXqo4T4fS6fDyNeqRAIE5CXDguBXUi8kZVb4FGg0U= -github.com/textileio/powergate/v2 v2.1.1-0.20210226193238-217dae95e6e1 h1:W0AHqVgtPU0mGaWUAcm7p/1zxnmFjjsElEgTCjlQYsY= -github.com/textileio/powergate/v2 v2.1.1-0.20210226193238-217dae95e6e1/go.mod h1:2mZQwhHWbb4PLpy+zlUd6oZAOS84PtghwiCKrnsV9B8= +github.com/textileio/powergate/v2 v2.2.1-0.20210303000513-0d6f65779af2 h1:Ll4g/oam8Bpgqh7p63/8LS0xb96DIQaGaZDGKne4+k4= +github.com/textileio/powergate/v2 v2.2.1-0.20210303000513-0d6f65779af2/go.mod h1:MxwU95rhpoSBsrKk5hWf4y6tGXbW4na8ta1FPlzWIFI= github.com/texttheater/golang-levenshtein v0.0.0-20180516184445-d188e65d659e/go.mod h1:XDKHRm5ThF8YJjx001LtgelzsoaEcvnA7lVWz9EeX3g= github.com/tidwall/gjson v1.3.5 h1:2oW9FBNu8qt9jy5URgrzsVx/T/KSn3qn/smJQ0crlDQ= github.com/tidwall/gjson v1.3.5/go.mod h1:P256ACg0Mn+j1RXIDXoss50DeIABTYK1PULOJHhxOls= @@ -1832,6 +1836,8 @@ github.com/whyrusleeping/cbor-gen v0.0.0-20200826160007-0b9f6c5fb163 h1:TtcUeY2X github.com/whyrusleeping/cbor-gen v0.0.0-20200826160007-0b9f6c5fb163/go.mod h1:fgkXqYy7bV2cFeIEOkVTZS/WjXARfBqSH6Q2qHL33hQ= github.com/whyrusleeping/cbor-gen v0.0.0-20210118024343-169e9d70c0c2 h1:7HzUKl5d/dELS9lLeT4W6YvliZx+s9k/eOOIdHKrA/w= github.com/whyrusleeping/cbor-gen v0.0.0-20210118024343-169e9d70c0c2/go.mod h1:fgkXqYy7bV2cFeIEOkVTZS/WjXARfBqSH6Q2qHL33hQ= +github.com/whyrusleeping/cbor-gen v0.0.0-20210219115102-f37d292932f2 h1:bsUlNhdmbtlfdLVXAVfuvKQ01RnWAM09TVrJkI7NZs4= +github.com/whyrusleeping/cbor-gen v0.0.0-20210219115102-f37d292932f2/go.mod h1:fgkXqYy7bV2cFeIEOkVTZS/WjXARfBqSH6Q2qHL33hQ= github.com/whyrusleeping/chunker v0.0.0-20181014151217-fe64bd25879f h1:jQa4QT2UP9WYv2nzyawpKMOCl+Z/jW7djv2/J50lj9E= github.com/whyrusleeping/chunker v0.0.0-20181014151217-fe64bd25879f/go.mod h1:p9UJB6dDgdPgMJZs7UjUOdulKyRr9fqkS+6JKAInPy8= github.com/whyrusleeping/go-ctrlnet v0.0.0-20180313164037-f564fbbdaa95/go.mod h1:SJqKCCPXRfBFCwXjfNT/skfsceF7+MBFLI2OrvuRA7g= @@ -2372,6 +2378,8 @@ gopkg.in/yaml.v2 v2.2.7/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU= gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo= From 20450fa2bc3b300a4f9d4f181a2530ffb2e08dba Mon Sep 17 00:00:00 2001 From: Aaron Sutula Date: Wed, 3 Mar 2021 09:52:06 -0600 Subject: [PATCH 07/16] fix config bug Signed-off-by: Aaron Sutula --- api/sendfild/main.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/api/sendfild/main.go b/api/sendfild/main.go index 6379cdfa6..2c5ffcec1 100644 --- a/api/sendfild/main.go +++ b/api/sendfild/main.go @@ -166,7 +166,7 @@ var rootCmd = &cobra.Command{ mongoUri := config.Viper.GetString("mongo_uri") mongoDb := config.Viper.GetString("mongo_db") messageTimeout := config.Viper.GetDuration("message_timeout") - messageConfidence := config.Viper.GetInt64("message_confidence") + messageConfidence := config.Viper.GetUint64("message_confidence") if logFile != "" { err = cmd.SetupDefaultLoggingConfig(logFile) @@ -186,7 +186,7 @@ var rootCmd = &cobra.Command{ MongoUri: mongoUri, MongoDbName: mongoDb, MessageWaitTimeout: messageTimeout, - MessageConfidence: uint64(messageConfidence), + MessageConfidence: messageConfidence, Debug: debug, } api, err := service.New(ctx, conf) From a3275c2377e53e09d776d022ea5cba34890e6810 Mon Sep 17 00:00:00 2001 From: Aaron Sutula Date: Wed, 3 Mar 2021 10:08:16 -0600 Subject: [PATCH 08/16] more config fix Signed-off-by: Aaron Sutula --- api/sendfild/main.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/api/sendfild/main.go b/api/sendfild/main.go index 2c5ffcec1..1e028352e 100644 --- a/api/sendfild/main.go +++ b/api/sendfild/main.go @@ -123,9 +123,9 @@ func init() { config.Flags["messageWaitTimeout"].DefValue.(time.Duration), "Timeout for listening for messages to become active on chain") - rootCmd.PersistentFlags().Int64( + rootCmd.PersistentFlags().Uint64( "messageConfidence", - config.Flags["messageConfidence"].DefValue.(int64), + config.Flags["messageConfidence"].DefValue.(uint64), "Confidence, in epochs, used to consider a message active on chain", ) From f48c2e8a45d20560d01e288161fcb9cf8c79ca07 Mon Sep 17 00:00:00 2001 From: Aaron Sutula Date: Wed, 3 Mar 2021 12:59:14 -0600 Subject: [PATCH 09/16] query for txns to be monitored on start up and recurring Signed-off-by: Aaron Sutula --- api/sendfild/main.go | 14 ++- api/sendfild/service/service.go | 64 ++++++++++- api/sendfild/service/service_test.go | 155 ++++++++++++++++++++------- 3 files changed, 191 insertions(+), 42 deletions(-) diff --git a/api/sendfild/main.go b/api/sendfild/main.go index 1e028352e..690238cbd 100644 --- a/api/sendfild/main.go +++ b/api/sendfild/main.go @@ -66,6 +66,10 @@ var ( Key: "message_confidence", DefValue: uint64(2), }, + "retryWaitFrequency": { + Key: "retry_wait_frequency", + DefValue: time.Minute, + }, }, EnvPre: "SENDFIL", Global: true, @@ -122,12 +126,14 @@ func init() { "messageWaitTimeout", config.Flags["messageWaitTimeout"].DefValue.(time.Duration), "Timeout for listening for messages to become active on chain") - rootCmd.PersistentFlags().Uint64( "messageConfidence", config.Flags["messageConfidence"].DefValue.(uint64), - "Confidence, in epochs, used to consider a message active on chain", - ) + "Confidence, in epochs, used to consider a message active on chain") + rootCmd.PersistentFlags().Duration( + "retryWaitFrequency", + config.Flags["retryWaitFrequency"].DefValue.(time.Duration), + "Frequency with which to query for txns that need to be monitored for completion") err := cmd.BindFlags(config.Viper, rootCmd, config.Flags) cmd.ErrCheck(err) @@ -167,6 +173,7 @@ var rootCmd = &cobra.Command{ mongoDb := config.Viper.GetString("mongo_db") messageTimeout := config.Viper.GetDuration("message_timeout") messageConfidence := config.Viper.GetUint64("message_confidence") + retryWaitFrequency := config.Viper.GetDuration("retry_wait_frequency") if logFile != "" { err = cmd.SetupDefaultLoggingConfig(logFile) @@ -187,6 +194,7 @@ var rootCmd = &cobra.Command{ MongoDbName: mongoDb, MessageWaitTimeout: messageTimeout, MessageConfidence: messageConfidence, + RetryWaitFrequency: retryWaitFrequency, Debug: debug, } api, err := service.New(ctx, conf) diff --git a/api/sendfild/service/service.go b/api/sendfild/service/service.go index 824c186de..2352a230f 100644 --- a/api/sendfild/service/service.go +++ b/api/sendfild/service/service.go @@ -7,6 +7,7 @@ import ( "math" "math/big" "net" + "strings" "sync" "time" @@ -66,6 +67,7 @@ type Service struct { server *grpc.Server waiting map[primitive.ObjectID]chan waitResult config Config + ticker *time.Ticker waitingLck sync.Mutex } @@ -76,6 +78,7 @@ type Config struct { MongoDbName string MessageWaitTimeout time.Duration MessageConfidence uint64 + RetryWaitFrequency time.Duration Debug bool } @@ -132,6 +135,7 @@ func New(ctx context.Context, config Config) (*Service, error) { col: col, waiting: make(map[primitive.ObjectID]chan waitResult), config: config, + ticker: time.NewTicker(config.RetryWaitFrequency), } s.server = grpc.NewServer() @@ -142,9 +146,51 @@ func New(ctx context.Context, config Config) (*Service, error) { } }() + if err := s.waitAllQualifying(ctx, true); err != nil { + return nil, fmt.Errorf("calling waitAllQualifying: %v", err) + } + + s.bindTicker(ctx) + return s, nil } +func (s *Service) waitAllQualifying(ctx context.Context, isInitialRun bool) error { + filter := bson.M{"$and": bson.A{ + bson.M{"message_state": bson.M{"$ne": pb.MessageState_MESSAGE_STATE_ACTIVE}}, + bson.M{"message_state": bson.M{"$ne": pb.MessageState_MESSAGE_STATE_FAILED}}, + }} + if !isInitialRun { + filter["waiting"] = false + } + cursor, err := s.col.Find(ctx, filter) + if err != nil { + return status.Errorf(codes.Internal, "querying txns: %v", err) + } + defer cursor.Close(ctx) + var txns []txn + err = cursor.All(ctx, &txns) + if err != nil { + return status.Errorf(codes.Internal, "decoding txns query results: %v", err) + } + log.Infof("found %v txns to initiate waiting on", len(txns)) + for _, txn := range txns { + s.wait(txn) + } + return nil +} + +func (s *Service) bindTicker(ctx context.Context) { + go func() { + for { + <-s.ticker.C + if err := s.waitAllQualifying(ctx, false); err != nil { + log.Errorf("waitAllQualifying from ticker: %v", err) + } + } + }() +} + func (s *Service) SendFil(ctx context.Context, req *pb.SendFilRequest) (*pb.SendFilResponse, error) { f, err := address.NewFromString(req.From) if err != nil { @@ -509,6 +555,7 @@ func (s *Service) wait(tx txn) chan waitResult { tx.MessageState = pb.MessageState_MESSAGE_STATE_FAILED tx.FailureMsg = fmt.Sprintf("getting latest message cid from txn: %v", err) tx.UpdatedAt = time.Now() + log.Warnf("failing txn with err: %s", tx.FailureMsg) if err := s.updateTxn(ctx, tx); err != nil { ch <- waitResult{err: err} return @@ -521,6 +568,7 @@ func (s *Service) wait(tx txn) chan waitResult { tx.MessageState = pb.MessageState_MESSAGE_STATE_FAILED tx.FailureMsg = fmt.Sprintf("decoding latest message cid for txn: %v", err) tx.UpdatedAt = time.Now() + log.Warnf("failing txn with err: %s", tx.FailureMsg) if err := s.updateTxn(ctx, tx); err != nil { ch <- waitResult{err: err} return @@ -538,11 +586,22 @@ func (s *Service) wait(tx txn) chan waitResult { res, err := client.StateWaitMsg(ctx, c, s.config.MessageConfidence) tx.Waiting = false if err != nil { + // If for some reason the lotus node doesn't know about the cid, consider that a final error. + if strings.Contains(err.Error(), "block not found") { + tx.MessageState = pb.MessageState_MESSAGE_STATE_FAILED + tx.FailureMsg = err.Error() + tx.UpdatedAt = time.Now() + log.Warnf("failing txn with err: %s", tx.FailureMsg) + } if err := s.updateTxn(ctx, tx); err != nil { ch <- waitResult{err: err} return } - ch <- waitResult{err: fmt.Errorf("calling StateWaitMsg: %v", err)} + if tx.MessageState == pb.MessageState_MESSAGE_STATE_FAILED { + ch <- waitResult{txn: tx} + } else { + ch <- waitResult{err: fmt.Errorf("calling StateWaitMsg: %v", err)} + } return } @@ -550,6 +609,7 @@ func (s *Service) wait(tx txn) chan waitResult { tx.MessageState = pb.MessageState_MESSAGE_STATE_FAILED tx.FailureMsg = fmt.Sprintf("error exit code: %v", res.Receipt.ExitCode.Error()) tx.UpdatedAt = time.Now() + log.Warnf("failing txn with err: %s", tx.FailureMsg) if err := s.updateTxn(ctx, tx); err != nil { ch <- waitResult{err: err} return @@ -596,6 +656,8 @@ func (s *Service) wait(tx txn) chan waitResult { } func (s *Service) Close() { + s.ticker.Stop() + ctx, cancel := context.WithTimeout(context.Background(), time.Second) defer cancel() if err := s.col.Database().Client().Disconnect(ctx); err != nil { diff --git a/api/sendfild/service/service_test.go b/api/sendfild/service/service_test.go index 28bf7b185..536174729 100644 --- a/api/sendfild/service/service_test.go +++ b/api/sendfild/service/service_test.go @@ -16,6 +16,7 @@ import ( mh "github.com/multiformats/go-multihash" "github.com/stretchr/testify/require" "github.com/textileio/go-ds-mongo/test" + "github.com/textileio/powergate/v2/lotus" "github.com/textileio/powergate/v2/tests" powutil "github.com/textileio/powergate/v2/util" pb "github.com/textileio/textile/v2/api/sendfild/pb" @@ -48,8 +49,35 @@ func TestMain(m *testing.M) { os.Exit(exitVal) } +func TestRestartWaiting(t *testing.T) { + cb, lc, dAddr, cleanupLotus := requireSetupLotus(t, ctx, setupWithSpeed(1000)) + defer cleanupLotus() + + c, cleanupService := requireSetupService(t, ctx, cb, setupWithDbName("restart_waiting")) + addr := requireLotusAddress(t, ctx, lc) + requireSendFil(t, ctx, c, dAddr.String(), addr.String(), oneFil, true) + requireSendFil(t, ctx, c, dAddr.String(), addr.String(), oneFil, false) + requireSendFil(t, ctx, c, dAddr.String(), addr.String(), oneFil, false) + requireSendFil(t, ctx, c, dAddr.String(), addr.String(), oneFil, false) + time.Sleep(time.Millisecond * 100) // Little time to allow the monitoring process to start waiting for all the txns. + res, err := c.Summary(ctx, &pb.SummaryRequest{}) + require.NoError(t, err) + require.Equal(t, int64(3), res.CountWaiting) + require.Equal(t, int64(3), res.CountPending) + require.Equal(t, int64(1), res.CountActive) + cleanupService() + c, cleanupService = requireSetupService(t, ctx, cb, setupWithDbName("restart_waiting")) + defer cleanupService() + time.Sleep(time.Millisecond * 100) // Little time to allow the monitoring process to start waiting for all the txns. + res, err = c.Summary(ctx, &pb.SummaryRequest{}) + require.NoError(t, err) + require.Equal(t, int64(3), res.CountWaiting) + require.Equal(t, int64(3), res.CountPending) + require.Equal(t, int64(1), res.CountActive) +} + func TestSendFil(t *testing.T) { - c, lc, dAddr, cleanup := requireSetup(t, ctx, 300) + c, lc, dAddr, cleanup := requireSetup(t, ctx) defer cleanup() addr := requireLotusAddress(t, ctx, lc) txn := requireSendFil(t, ctx, c, dAddr.String(), addr.String(), oneFil, false) @@ -57,7 +85,7 @@ func TestSendFil(t *testing.T) { } func TestSendFilWait(t *testing.T) { - c, lc, dAddr, cleanup := requireSetup(t, ctx, 300) + c, lc, dAddr, cleanup := requireSetup(t, ctx) defer cleanup() addr := requireLotusAddress(t, ctx, lc) txn := requireSendFil(t, ctx, c, dAddr.String(), addr.String(), oneFil, true) @@ -65,7 +93,7 @@ func TestSendFilWait(t *testing.T) { } func TestTxn(t *testing.T) { - c, lc, dAddr, cleanup := requireSetup(t, ctx, 1000) + c, lc, dAddr, cleanup := requireSetup(t, ctx, setupWithSpeed(1000)) defer cleanup() addr := requireLotusAddress(t, ctx, lc) txn := requireSendFil(t, ctx, c, dAddr.String(), addr.String(), oneFil, false) @@ -76,7 +104,7 @@ func TestTxn(t *testing.T) { } func TestTxnWait(t *testing.T) { - c, lc, dAddr, cleanup := requireSetup(t, ctx, 300) + c, lc, dAddr, cleanup := requireSetup(t, ctx) defer cleanup() addr := requireLotusAddress(t, ctx, lc) txn1 := requireSendFil(t, ctx, c, dAddr.String(), addr.String(), oneFil, false) @@ -87,14 +115,14 @@ func TestTxnWait(t *testing.T) { } func TestTxnNonExistent(t *testing.T) { - c, _, _, cleanup := requireSetup(t, ctx, 300) + c, _, _, cleanup := requireSetup(t, ctx) defer cleanup() _, err := c.Txn(ctx, &pb.TxnRequest{MessageCid: randomCid().String()}) require.Equal(t, codes.NotFound, status.Code(err)) } func TestListTxns(t *testing.T) { - c, lc, dAddr, cleanup := requireSetup(t, ctx, 300) + c, lc, dAddr, cleanup := requireSetup(t, ctx) defer cleanup() addr := requireLotusAddress(t, ctx, lc) requireSendFil(t, ctx, c, dAddr.String(), addr.String(), oneFil, false) @@ -106,7 +134,7 @@ func TestListTxns(t *testing.T) { } func TestListTxnsFrom(t *testing.T) { - c, lc, dAddr, cleanup := requireSetup(t, ctx, 300) + c, lc, dAddr, cleanup := requireSetup(t, ctx) defer cleanup() addr1 := requireLotusAddress(t, ctx, lc) addr2 := requireLotusAddress(t, ctx, lc) @@ -123,7 +151,7 @@ func TestListTxnsFrom(t *testing.T) { } func TestListTxnsTo(t *testing.T) { - c, lc, dAddr, cleanup := requireSetup(t, ctx, 300) + c, lc, dAddr, cleanup := requireSetup(t, ctx) defer cleanup() addr1 := requireLotusAddress(t, ctx, lc) addr2 := requireLotusAddress(t, ctx, lc) @@ -140,7 +168,7 @@ func TestListTxnsTo(t *testing.T) { } func TestListTxnsInvolving(t *testing.T) { - c, lc, dAddr, cleanup := requireSetup(t, ctx, 300) + c, lc, dAddr, cleanup := requireSetup(t, ctx) defer cleanup() addr1 := requireLotusAddress(t, ctx, lc) addr2 := requireLotusAddress(t, ctx, lc) @@ -160,7 +188,7 @@ func TestListTxnsInvolving(t *testing.T) { } func TestListTxnsAmtGt(t *testing.T) { - c, lc, dAddr, cleanup := requireSetup(t, ctx, 300) + c, lc, dAddr, cleanup := requireSetup(t, ctx) defer cleanup() addr1 := requireLotusAddress(t, ctx, lc) requireSendFil(t, ctx, c, dAddr.String(), addr1.String(), oneFil/2, false) @@ -175,7 +203,7 @@ func TestListTxnsAmtGt(t *testing.T) { } func TestListTxnsAmtGteq(t *testing.T) { - c, lc, dAddr, cleanup := requireSetup(t, ctx, 300) + c, lc, dAddr, cleanup := requireSetup(t, ctx) defer cleanup() addr1 := requireLotusAddress(t, ctx, lc) requireSendFil(t, ctx, c, dAddr.String(), addr1.String(), oneFil/2, false) @@ -190,7 +218,7 @@ func TestListTxnsAmtGteq(t *testing.T) { } func TestListTxnsAmtLt(t *testing.T) { - c, lc, dAddr, cleanup := requireSetup(t, ctx, 300) + c, lc, dAddr, cleanup := requireSetup(t, ctx) defer cleanup() addr1 := requireLotusAddress(t, ctx, lc) requireSendFil(t, ctx, c, dAddr.String(), addr1.String(), oneFil/2, false) @@ -205,7 +233,7 @@ func TestListTxnsAmtLt(t *testing.T) { } func TestListTxnsAmtLteq(t *testing.T) { - c, lc, dAddr, cleanup := requireSetup(t, ctx, 300) + c, lc, dAddr, cleanup := requireSetup(t, ctx) defer cleanup() addr1 := requireLotusAddress(t, ctx, lc) requireSendFil(t, ctx, c, dAddr.String(), addr1.String(), oneFil/2, false) @@ -220,7 +248,7 @@ func TestListTxnsAmtLteq(t *testing.T) { } func TestListTxnsAmtGtLt(t *testing.T) { - c, lc, dAddr, cleanup := requireSetup(t, ctx, 300) + c, lc, dAddr, cleanup := requireSetup(t, ctx) defer cleanup() addr1 := requireLotusAddress(t, ctx, lc) requireSendFil(t, ctx, c, dAddr.String(), addr1.String(), oneFil/2, false) @@ -232,7 +260,7 @@ func TestListTxnsAmtGtLt(t *testing.T) { } func TestListTxnsAmtGteqLteq(t *testing.T) { - c, lc, dAddr, cleanup := requireSetup(t, ctx, 300) + c, lc, dAddr, cleanup := requireSetup(t, ctx) defer cleanup() addr1 := requireLotusAddress(t, ctx, lc) requireSendFil(t, ctx, c, dAddr.String(), addr1.String(), oneFil/2, false) @@ -245,7 +273,7 @@ func TestListTxnsAmtGteqLteq(t *testing.T) { } func TestListTxnsAmtGteqLt(t *testing.T) { - c, lc, dAddr, cleanup := requireSetup(t, ctx, 300) + c, lc, dAddr, cleanup := requireSetup(t, ctx) defer cleanup() addr1 := requireLotusAddress(t, ctx, lc) requireSendFil(t, ctx, c, dAddr.String(), addr1.String(), oneFil/2, false) @@ -257,7 +285,7 @@ func TestListTxnsAmtGteqLt(t *testing.T) { } func TestListTxnsAmtGtLteq(t *testing.T) { - c, lc, dAddr, cleanup := requireSetup(t, ctx, 300) + c, lc, dAddr, cleanup := requireSetup(t, ctx) defer cleanup() addr1 := requireLotusAddress(t, ctx, lc) requireSendFil(t, ctx, c, dAddr.String(), addr1.String(), oneFil/2, false) @@ -270,7 +298,7 @@ func TestListTxnsAmtGtLteq(t *testing.T) { } func TestListTxnsAmtEq(t *testing.T) { - c, lc, dAddr, cleanup := requireSetup(t, ctx, 300) + c, lc, dAddr, cleanup := requireSetup(t, ctx) defer cleanup() addr1 := requireLotusAddress(t, ctx, lc) requireSendFil(t, ctx, c, dAddr.String(), addr1.String(), oneFil/2, false) @@ -283,7 +311,7 @@ func TestListTxnsAmtEq(t *testing.T) { } func TestListTxnsMessageState(t *testing.T) { - c, lc, dAddr, cleanup := requireSetup(t, ctx, 1000) + c, lc, dAddr, cleanup := requireSetup(t, ctx, setupWithSpeed(1000)) defer cleanup() addr1 := requireLotusAddress(t, ctx, lc) requireSendFil(t, ctx, c, dAddr.String(), addr1.String(), oneFil, true) @@ -298,7 +326,7 @@ func TestListTxnsMessageState(t *testing.T) { } func TestListTxnsWaiting(t *testing.T) { - c, lc, dAddr, cleanup := requireSetup(t, ctx, 1000) + c, lc, dAddr, cleanup := requireSetup(t, ctx, setupWithSpeed(1000)) defer cleanup() addr1 := requireLotusAddress(t, ctx, lc) requireSendFil(t, ctx, c, dAddr.String(), addr1.String(), oneFil, true) @@ -314,7 +342,7 @@ func TestListTxnsWaiting(t *testing.T) { } func TestListTxnsCreatedAfter(t *testing.T) { - c, lc, dAddr, cleanup := requireSetup(t, ctx, 300) + c, lc, dAddr, cleanup := requireSetup(t, ctx) defer cleanup() addr1 := requireLotusAddress(t, ctx, lc) t1 := requireSendFil(t, ctx, c, dAddr.String(), addr1.String(), oneFil, false) @@ -326,7 +354,7 @@ func TestListTxnsCreatedAfter(t *testing.T) { } func TestListTxnsCreatedBefore(t *testing.T) { - c, lc, dAddr, cleanup := requireSetup(t, ctx, 300) + c, lc, dAddr, cleanup := requireSetup(t, ctx) defer cleanup() addr1 := requireLotusAddress(t, ctx, lc) requireSendFil(t, ctx, c, dAddr.String(), addr1.String(), oneFil, false) @@ -338,7 +366,7 @@ func TestListTxnsCreatedBefore(t *testing.T) { } func TestListTxnsCreatedAfterBefore(t *testing.T) { - c, lc, dAddr, cleanup := requireSetup(t, ctx, 300) + c, lc, dAddr, cleanup := requireSetup(t, ctx) defer cleanup() addr1 := requireLotusAddress(t, ctx, lc) t1 := requireSendFil(t, ctx, c, dAddr.String(), addr1.String(), oneFil, false) @@ -350,7 +378,7 @@ func TestListTxnsCreatedAfterBefore(t *testing.T) { } func TestListTxnsUpdatedAfter(t *testing.T) { - c, lc, dAddr, cleanup := requireSetup(t, ctx, 300) + c, lc, dAddr, cleanup := requireSetup(t, ctx) defer cleanup() addr1 := requireLotusAddress(t, ctx, lc) t1 := requireSendFil(t, ctx, c, dAddr.String(), addr1.String(), oneFil, false) @@ -362,7 +390,7 @@ func TestListTxnsUpdatedAfter(t *testing.T) { } func TestListTxnsUpdatedBefore(t *testing.T) { - c, lc, dAddr, cleanup := requireSetup(t, ctx, 300) + c, lc, dAddr, cleanup := requireSetup(t, ctx) defer cleanup() addr1 := requireLotusAddress(t, ctx, lc) requireSendFil(t, ctx, c, dAddr.String(), addr1.String(), oneFil, false) @@ -374,7 +402,7 @@ func TestListTxnsUpdatedBefore(t *testing.T) { } func TestListTxnsUpdatedAfterBefore(t *testing.T) { - c, lc, dAddr, cleanup := requireSetup(t, ctx, 300) + c, lc, dAddr, cleanup := requireSetup(t, ctx) defer cleanup() addr1 := requireLotusAddress(t, ctx, lc) t1 := requireSendFil(t, ctx, c, dAddr.String(), addr1.String(), oneFil, false) @@ -386,7 +414,7 @@ func TestListTxnsUpdatedAfterBefore(t *testing.T) { } func TestListTxnsOrder(t *testing.T) { - c, lc, dAddr, cleanup := requireSetup(t, ctx, 300) + c, lc, dAddr, cleanup := requireSetup(t, ctx) defer cleanup() addr1 := requireLotusAddress(t, ctx, lc) requireSendFil(t, ctx, c, dAddr.String(), addr1.String(), oneFil, false) @@ -403,7 +431,7 @@ func TestListTxnsOrder(t *testing.T) { } func TestListTxnsPaging(t *testing.T) { - c, lc, dAddr, cleanup := requireSetup(t, ctx, 300) + c, lc, dAddr, cleanup := requireSetup(t, ctx) defer cleanup() addr1 := requireLotusAddress(t, ctx, lc) txFirst := requireSendFil(t, ctx, c, dAddr.String(), addr1.String(), oneFil, false) @@ -450,7 +478,7 @@ func TestListTxnsPaging(t *testing.T) { } func TestSummary(t *testing.T) { - c, lc, dAddr, cleanup := requireSetup(t, ctx, 1000) + c, lc, dAddr, cleanup := requireSetup(t, ctx, setupWithSpeed(1000)) defer cleanup() addr1 := requireLotusAddress(t, ctx, lc) addr2 := requireLotusAddress(t, ctx, lc) @@ -487,19 +515,61 @@ func TestSummary(t *testing.T) { require.Equal(t, int64(oneFil*4), res.TotalNanoFilSent) } -func requireSetup(t *testing.T, ctx context.Context, speed int) (pb.SendFilServiceClient, *apistruct.FullNodeStruct, address.Address, func()) { - clientBuilder, addr, _ := tests.CreateLocalDevnet(t, 1, speed) +type setupConfig struct { + dbName string + speed int +} + +type setupOption = func(*setupConfig) + +func setupWithSpeed(speed int) setupOption { + return func(config *setupConfig) { + config.speed = speed + } +} + +func setupWithDbName(dbName string) setupOption { + return func(config *setupConfig) { + config.dbName = dbName + } +} + +func requireSetupLotus(t *testing.T, ctx context.Context, opts ...setupOption) (lotus.ClientBuilder, *apistruct.FullNodeStruct, address.Address, func()) { + config := &setupConfig{ + speed: 300, + } + for _, opt := range opts { + opt(config) + } + clientBuilder, addr, _ := tests.CreateLocalDevnet(t, 1, config.speed) time.Sleep(time.Millisecond * 500) // Allow the network to some tipsets + lotusClient, closeLotusClient, err := clientBuilder(ctx) + require.NoError(t, err) + + cleanup := func() { + closeLotusClient() + } + return clientBuilder, lotusClient, addr, cleanup +} + +func requireSetupService(t *testing.T, ctx context.Context, cb lotus.ClientBuilder, opts ...setupOption) (pb.SendFilServiceClient, func()) { + config := &setupConfig{ + dbName: util.MakeToken(12), + } + for _, opt := range opts { + opt(config) + } listener := bufconn.Listen(bufSize) conf := Config{ Listener: listener, - ClientBuilder: clientBuilder, + ClientBuilder: cb, MongoUri: test.GetMongoUri(), - MongoDbName: util.MakeToken(12), + MongoDbName: config.dbName, MessageWaitTimeout: time.Minute, MessageConfidence: 2, + RetryWaitFrequency: time.Minute, Debug: true, } s, err := New(ctx, conf) @@ -513,16 +583,25 @@ func requireSetup(t *testing.T, ctx context.Context, speed int) (pb.SendFilServi require.NoError(t, err) client := pb.NewSendFilServiceClient(conn) - lotusClient, closeLotusClient, err := clientBuilder(ctx) - require.NoError(t, err) - cleanup := func() { conn.Close() s.Close() - closeLotusClient() } - return client, lotusClient, addr, cleanup + return client, cleanup +} + +func requireSetup(t *testing.T, ctx context.Context, opts ...setupOption) (pb.SendFilServiceClient, *apistruct.FullNodeStruct, address.Address, func()) { + + cb, lotusClient, addr, cleanupLouts := requireSetupLotus(t, ctx, opts...) + serviceClient, cleanupService := requireSetupService(t, ctx, cb, opts...) + + cleanup := func() { + cleanupLouts() + cleanupService() + } + + return serviceClient, lotusClient, addr, cleanup } func requireLotusAddress(t *testing.T, ctx context.Context, lotusClient *apistruct.FullNodeStruct) address.Address { From a351a4749dae363030c7d9600bd3131d08ce020a Mon Sep 17 00:00:00 2001 From: Aaron Sutula Date: Wed, 3 Mar 2021 17:34:27 -0600 Subject: [PATCH 10/16] point at latest powergate commit needed Signed-off-by: Aaron Sutula --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 076b681dd..6ef37d5a8 100644 --- a/go.mod +++ b/go.mod @@ -74,7 +74,7 @@ require ( github.com/textileio/go-assets v0.0.0-20200430191519-b341e634e2b7 github.com/textileio/go-ds-mongo v0.1.5-0.20201230201018-2b7fdca787a5 github.com/textileio/go-threads v1.0.3-0.20201216032729-f7b034a0de80 - github.com/textileio/powergate/v2 v2.2.1-0.20210303000513-0d6f65779af2 + github.com/textileio/powergate/v2 v2.2.1-0.20210303232835-2587790b227c github.com/xakep666/mongo-migrate v0.2.1 github.com/xtgo/uuid v0.0.0-20140804021211-a0b114877d4c // indirect go.mongodb.org/mongo-driver v1.4.1 diff --git a/go.sum b/go.sum index 391b3e1d2..9d752b1e4 100644 --- a/go.sum +++ b/go.sum @@ -1771,8 +1771,8 @@ github.com/textileio/go-ds-mongo v0.1.5-0.20201230201018-2b7fdca787a5 h1:wy2WAFw github.com/textileio/go-ds-mongo v0.1.5-0.20201230201018-2b7fdca787a5/go.mod h1:Zf6JlMPiIQUUmGlFFn5Z65C9p9LAvPg7XvX+qdGmTsU= github.com/textileio/go-threads v1.0.3-0.20201216032729-f7b034a0de80 h1:UJbiLtEmaRp9zUif+thvxsIOkeZnTECIWcaURCBaXS4= github.com/textileio/go-threads v1.0.3-0.20201216032729-f7b034a0de80/go.mod h1:kvIXqo4T4fS6fDyNeqRAIE5CXDguBXUi8kZVb4FGg0U= -github.com/textileio/powergate/v2 v2.2.1-0.20210303000513-0d6f65779af2 h1:Ll4g/oam8Bpgqh7p63/8LS0xb96DIQaGaZDGKne4+k4= -github.com/textileio/powergate/v2 v2.2.1-0.20210303000513-0d6f65779af2/go.mod h1:MxwU95rhpoSBsrKk5hWf4y6tGXbW4na8ta1FPlzWIFI= +github.com/textileio/powergate/v2 v2.2.1-0.20210303232835-2587790b227c h1:/zBUukCG1U2jyKL8YpO9Xgu+AN2aKJpLtNW2uDxmMN8= +github.com/textileio/powergate/v2 v2.2.1-0.20210303232835-2587790b227c/go.mod h1:MxwU95rhpoSBsrKk5hWf4y6tGXbW4na8ta1FPlzWIFI= github.com/texttheater/golang-levenshtein v0.0.0-20180516184445-d188e65d659e/go.mod h1:XDKHRm5ThF8YJjx001LtgelzsoaEcvnA7lVWz9EeX3g= github.com/tidwall/gjson v1.3.5 h1:2oW9FBNu8qt9jy5URgrzsVx/T/KSn3qn/smJQ0crlDQ= github.com/tidwall/gjson v1.3.5/go.mod h1:P256ACg0Mn+j1RXIDXoss50DeIABTYK1PULOJHhxOls= From a6438719f431fd85cc793fc5c21ea44cefa9ddd3 Mon Sep 17 00:00:00 2001 From: Aaron Sutula Date: Fri, 5 Mar 2021 10:11:25 -0600 Subject: [PATCH 11/16] few fixes around service config and docker ports Signed-off-by: Aaron Sutula --- api/sendfild/Dockerfile | 2 +- api/sendfild/Dockerfile.dev | 3 +-- api/sendfild/main.go | 9 +++------ api/sendfild/service/service.go | 21 ++++++++++++++++++--- api/sendfild/service/service_test.go | 2 +- 5 files changed, 24 insertions(+), 13 deletions(-) diff --git a/api/sendfild/Dockerfile b/api/sendfild/Dockerfile index b81a803bb..37460e165 100644 --- a/api/sendfild/Dockerfile +++ b/api/sendfild/Dockerfile @@ -60,7 +60,7 @@ COPY --from=0 /usr/lib/*-linux-gnu*/libssl.so* /usr/lib/ COPY --from=0 /usr/lib/*-linux-gnu*/libcrypto.so* /usr/lib/ # listenAddrs -EXPOSE 7006 +EXPOSE 5000 # Create the repo directory. ENV SENDFIL_PATH /data/sendfil diff --git a/api/sendfild/Dockerfile.dev b/api/sendfild/Dockerfile.dev index eee185310..40afc7e82 100644 --- a/api/sendfild/Dockerfile.dev +++ b/api/sendfild/Dockerfile.dev @@ -25,8 +25,7 @@ COPY --from=0 /go/bin/dlv /usr/local/bin/dlv COPY --from=0 /etc/ssl/certs /etc/ssl/certs COPY --from=0 $SRC_DIR/sendfild /usr/local/bin/sendfild -EXPOSE 10006 -EXPOSE 8010 +EXPOSE 5000 ENV SENDFIL_PATH /data/sendfil RUN adduser --home $SENDFIL_PATH --disabled-login --gecos "" --ingroup users sendfil diff --git a/api/sendfild/main.go b/api/sendfild/main.go index 690238cbd..5b9d65067 100644 --- a/api/sendfild/main.go +++ b/api/sendfild/main.go @@ -1,7 +1,6 @@ package main import ( - "context" "encoding/json" "fmt" "net" @@ -64,7 +63,7 @@ var ( }, "messageConfidence": { Key: "message_confidence", - DefValue: uint64(2), + DefValue: uint64(5), }, "retryWaitFrequency": { Key: "retry_wait_frequency", @@ -186,7 +185,6 @@ var rootCmd = &cobra.Command{ cb, err := lotus.NewBuilder(lotusAddr, lotusAuthToken, lotusConnRetries) cmd.ErrCheck(err) - ctx, cancel := context.WithCancel(context.Background()) conf := service.Config{ Listener: listener, ClientBuilder: cb, @@ -197,14 +195,13 @@ var rootCmd = &cobra.Command{ RetryWaitFrequency: retryWaitFrequency, Debug: debug, } - api, err := service.New(ctx, conf) + api, err := service.New(conf) cmd.ErrCheck(err) fmt.Println("Welcome to Hub Sendfil!") cmd.HandleInterrupt(func() { - api.Close() - cancel() + cmd.ErrCheck(api.Close()) }) }, } diff --git a/api/sendfild/service/service.go b/api/sendfild/service/service.go index 2352a230f..ed41f9b02 100644 --- a/api/sendfild/service/service.go +++ b/api/sendfild/service/service.go @@ -69,6 +69,7 @@ type Service struct { config Config ticker *time.Ticker waitingLck sync.Mutex + mainCtxCancel context.CancelFunc } type Config struct { @@ -82,17 +83,20 @@ type Config struct { Debug bool } -func New(ctx context.Context, config Config) (*Service, error) { +func New(config Config) (*Service, error) { + ctx, cancel := context.WithCancel(context.Background()) if config.Debug { if err := util.SetLogLevels(map[string]logging.LogLevel{ "sendfil": logging.LevelDebug, }); err != nil { + cancel() return nil, err } } client, err := mongo.Connect(ctx, options.Client().ApplyURI(config.MongoUri)) if err != nil { + cancel() return nil, fmt.Errorf("connecting to mongo: %v", err) } db := client.Database(config.MongoDbName) @@ -127,6 +131,7 @@ func New(ctx context.Context, config Config) (*Service, error) { Keys: bson.D{primitive.E{Key: "updated_at", Value: 1}}, }, }); err != nil { + cancel() return nil, fmt.Errorf("creating collection indexes: %v", err) } @@ -136,6 +141,7 @@ func New(ctx context.Context, config Config) (*Service, error) { waiting: make(map[primitive.ObjectID]chan waitResult), config: config, ticker: time.NewTicker(config.RetryWaitFrequency), + mainCtxCancel: cancel, } s.server = grpc.NewServer() @@ -147,6 +153,7 @@ func New(ctx context.Context, config Config) (*Service, error) { }() if err := s.waitAllQualifying(ctx, true); err != nil { + cancel() return nil, fmt.Errorf("calling waitAllQualifying: %v", err) } @@ -655,15 +662,19 @@ func (s *Service) wait(tx txn) chan waitResult { return ch } -func (s *Service) Close() { +func (s *Service) Close() error { + var e error + s.ticker.Stop() ctx, cancel := context.WithTimeout(context.Background(), time.Second) defer cancel() if err := s.col.Database().Client().Disconnect(ctx); err != nil { log.Errorf("disconnecting mongo client: %s", err) + e = err + } else { + log.Info("mongo client disconnected") } - log.Info("mongo client disconnected") stopped := make(chan struct{}) go func() { @@ -678,6 +689,10 @@ func (s *Service) Close() { t.Stop() } log.Info("gRPC server stopped") + + s.mainCtxCancel() + + return e } func (s *Service) updateTxn(ctx context.Context, t txn) error { diff --git a/api/sendfild/service/service_test.go b/api/sendfild/service/service_test.go index 536174729..de115a552 100644 --- a/api/sendfild/service/service_test.go +++ b/api/sendfild/service/service_test.go @@ -572,7 +572,7 @@ func requireSetupService(t *testing.T, ctx context.Context, cb lotus.ClientBuild RetryWaitFrequency: time.Minute, Debug: true, } - s, err := New(ctx, conf) + s, err := New(conf) require.NoError(t, err) bufDialer := func(context.Context, string) (net.Conn, error) { From 8b803252c0823bae7edef13d8cf0d7497db021b1 Mon Sep 17 00:00:00 2001 From: Aaron Sutula Date: Fri, 5 Mar 2021 10:40:03 -0600 Subject: [PATCH 12/16] txn > gettxn naming Signed-off-by: Aaron Sutula --- api/sendfild/client/client.go | 12 +- api/sendfild/pb/sendfil.pb.go | 367 ++++++++++++++------------- api/sendfild/pb/sendfil.proto | 6 +- api/sendfild/service/service.go | 4 +- api/sendfild/service/service_test.go | 12 +- 5 files changed, 201 insertions(+), 200 deletions(-) diff --git a/api/sendfild/client/client.go b/api/sendfild/client/client.go index fa30334d2..ec7c2ba12 100644 --- a/api/sendfild/client/client.go +++ b/api/sendfild/client/client.go @@ -53,22 +53,22 @@ func (c *Client) SendFil(ctx context.Context, from, to string, amountNanoFil int return res.Txn, nil } -type TxnOption = func(*pb.TxnRequest) +type GetTxnOption = func(*pb.GetTxnRequest) -func TxnWait() TxnOption { - return func(req *pb.TxnRequest) { +func GetTxnWait() GetTxnOption { + return func(req *pb.GetTxnRequest) { req.Wait = true } } -func (c *Client) Txn(ctx context.Context, messageCid string, opts ...TxnOption) (*pb.Txn, error) { - req := &pb.TxnRequest{ +func (c *Client) GetTxn(ctx context.Context, messageCid string, opts ...GetTxnOption) (*pb.Txn, error) { + req := &pb.GetTxnRequest{ MessageCid: messageCid, } for _, opt := range opts { opt(req) } - res, err := c.c.Txn(ctx, req) + res, err := c.c.GetTxn(ctx, req) if err != nil { return nil, err } diff --git a/api/sendfild/pb/sendfil.pb.go b/api/sendfild/pb/sendfil.pb.go index 73c2e40f9..ff7bf3f1f 100644 --- a/api/sendfild/pb/sendfil.pb.go +++ b/api/sendfild/pb/sendfil.pb.go @@ -368,7 +368,7 @@ func (x *SendFilResponse) GetTxn() *Txn { return nil } -type TxnRequest struct { +type GetTxnRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields @@ -377,8 +377,8 @@ type TxnRequest struct { Wait bool `protobuf:"varint,2,opt,name=wait,proto3" json:"wait,omitempty"` } -func (x *TxnRequest) Reset() { - *x = TxnRequest{} +func (x *GetTxnRequest) Reset() { + *x = GetTxnRequest{} if protoimpl.UnsafeEnabled { mi := &file_api_sendfild_pb_sendfil_proto_msgTypes[3] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -386,13 +386,13 @@ func (x *TxnRequest) Reset() { } } -func (x *TxnRequest) String() string { +func (x *GetTxnRequest) String() string { return protoimpl.X.MessageStringOf(x) } -func (*TxnRequest) ProtoMessage() {} +func (*GetTxnRequest) ProtoMessage() {} -func (x *TxnRequest) ProtoReflect() protoreflect.Message { +func (x *GetTxnRequest) ProtoReflect() protoreflect.Message { mi := &file_api_sendfild_pb_sendfil_proto_msgTypes[3] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -404,26 +404,26 @@ func (x *TxnRequest) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use TxnRequest.ProtoReflect.Descriptor instead. -func (*TxnRequest) Descriptor() ([]byte, []int) { +// Deprecated: Use GetTxnRequest.ProtoReflect.Descriptor instead. +func (*GetTxnRequest) Descriptor() ([]byte, []int) { return file_api_sendfild_pb_sendfil_proto_rawDescGZIP(), []int{3} } -func (x *TxnRequest) GetMessageCid() string { +func (x *GetTxnRequest) GetMessageCid() string { if x != nil { return x.MessageCid } return "" } -func (x *TxnRequest) GetWait() bool { +func (x *GetTxnRequest) GetWait() bool { if x != nil { return x.Wait } return false } -type TxnResponse struct { +type GetTxnResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields @@ -431,8 +431,8 @@ type TxnResponse struct { Txn *Txn `protobuf:"bytes,1,opt,name=txn,proto3" json:"txn,omitempty"` } -func (x *TxnResponse) Reset() { - *x = TxnResponse{} +func (x *GetTxnResponse) Reset() { + *x = GetTxnResponse{} if protoimpl.UnsafeEnabled { mi := &file_api_sendfild_pb_sendfil_proto_msgTypes[4] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -440,13 +440,13 @@ func (x *TxnResponse) Reset() { } } -func (x *TxnResponse) String() string { +func (x *GetTxnResponse) String() string { return protoimpl.X.MessageStringOf(x) } -func (*TxnResponse) ProtoMessage() {} +func (*GetTxnResponse) ProtoMessage() {} -func (x *TxnResponse) ProtoReflect() protoreflect.Message { +func (x *GetTxnResponse) ProtoReflect() protoreflect.Message { mi := &file_api_sendfild_pb_sendfil_proto_msgTypes[4] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -458,12 +458,12 @@ func (x *TxnResponse) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use TxnResponse.ProtoReflect.Descriptor instead. -func (*TxnResponse) Descriptor() ([]byte, []int) { +// Deprecated: Use GetTxnResponse.ProtoReflect.Descriptor instead. +func (*GetTxnResponse) Descriptor() ([]byte, []int) { return file_api_sendfild_pb_sendfil_proto_rawDescGZIP(), []int{4} } -func (x *TxnResponse) GetTxn() *Txn { +func (x *GetTxnResponse) GetTxn() *Txn { if x != nil { return x.Txn } @@ -932,154 +932,155 @@ var file_api_sendfild_pb_sendfil_proto_rawDesc = []byte{ 0x0f, 0x53, 0x65, 0x6e, 0x64, 0x46, 0x69, 0x6c, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x26, 0x0a, 0x03, 0x74, 0x78, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x73, 0x65, 0x6e, 0x64, 0x66, 0x69, 0x6c, 0x64, 0x2e, 0x70, 0x62, 0x2e, - 0x54, 0x78, 0x6e, 0x52, 0x03, 0x74, 0x78, 0x6e, 0x22, 0x41, 0x0a, 0x0a, 0x54, 0x78, 0x6e, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1f, 0x0a, 0x0b, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, - 0x65, 0x5f, 0x63, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x6d, 0x65, 0x73, - 0x73, 0x61, 0x67, 0x65, 0x43, 0x69, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x77, 0x61, 0x69, 0x74, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x04, 0x77, 0x61, 0x69, 0x74, 0x22, 0x35, 0x0a, 0x0b, 0x54, - 0x78, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x26, 0x0a, 0x03, 0x74, 0x78, - 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x73, 0x65, - 0x6e, 0x64, 0x66, 0x69, 0x6c, 0x64, 0x2e, 0x70, 0x62, 0x2e, 0x54, 0x78, 0x6e, 0x52, 0x03, 0x74, - 0x78, 0x6e, 0x22, 0x97, 0x07, 0x0a, 0x0f, 0x4c, 0x69, 0x73, 0x74, 0x54, 0x78, 0x6e, 0x73, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1f, 0x0a, 0x0b, 0x66, 0x72, 0x6f, 0x6d, 0x5f, 0x66, - 0x69, 0x6c, 0x74, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x66, 0x72, 0x6f, - 0x6d, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x12, 0x1b, 0x0a, 0x09, 0x74, 0x6f, 0x5f, 0x66, 0x69, - 0x6c, 0x74, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x74, 0x6f, 0x46, 0x69, - 0x6c, 0x74, 0x65, 0x72, 0x12, 0x29, 0x0a, 0x10, 0x69, 0x6e, 0x76, 0x6f, 0x6c, 0x76, 0x69, 0x6e, - 0x67, 0x5f, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, - 0x69, 0x6e, 0x76, 0x6f, 0x6c, 0x76, 0x69, 0x6e, 0x67, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x12, - 0x38, 0x0a, 0x19, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x6e, 0x61, 0x6e, 0x6f, 0x5f, 0x66, - 0x69, 0x6c, 0x5f, 0x6c, 0x74, 0x5f, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x18, 0x04, 0x20, 0x01, - 0x28, 0x03, 0x52, 0x15, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x4e, 0x61, 0x6e, 0x6f, 0x46, 0x69, - 0x6c, 0x4c, 0x74, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x12, 0x38, 0x0a, 0x19, 0x61, 0x6d, 0x6f, - 0x75, 0x6e, 0x74, 0x5f, 0x6e, 0x61, 0x6e, 0x6f, 0x5f, 0x66, 0x69, 0x6c, 0x5f, 0x67, 0x74, 0x5f, - 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, 0x52, 0x15, 0x61, 0x6d, - 0x6f, 0x75, 0x6e, 0x74, 0x4e, 0x61, 0x6e, 0x6f, 0x46, 0x69, 0x6c, 0x47, 0x74, 0x46, 0x69, 0x6c, - 0x74, 0x65, 0x72, 0x12, 0x3c, 0x0a, 0x1b, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x6e, 0x61, - 0x6e, 0x6f, 0x5f, 0x66, 0x69, 0x6c, 0x5f, 0x6c, 0x74, 0x65, 0x71, 0x5f, 0x66, 0x69, 0x6c, 0x74, - 0x65, 0x72, 0x18, 0x06, 0x20, 0x01, 0x28, 0x03, 0x52, 0x17, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, - 0x4e, 0x61, 0x6e, 0x6f, 0x46, 0x69, 0x6c, 0x4c, 0x74, 0x65, 0x71, 0x46, 0x69, 0x6c, 0x74, 0x65, - 0x72, 0x12, 0x3c, 0x0a, 0x1b, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x6e, 0x61, 0x6e, 0x6f, - 0x5f, 0x66, 0x69, 0x6c, 0x5f, 0x67, 0x74, 0x65, 0x71, 0x5f, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, - 0x18, 0x07, 0x20, 0x01, 0x28, 0x03, 0x52, 0x17, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x4e, 0x61, - 0x6e, 0x6f, 0x46, 0x69, 0x6c, 0x47, 0x74, 0x65, 0x71, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x12, + 0x54, 0x78, 0x6e, 0x52, 0x03, 0x74, 0x78, 0x6e, 0x22, 0x44, 0x0a, 0x0d, 0x47, 0x65, 0x74, 0x54, + 0x78, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1f, 0x0a, 0x0b, 0x6d, 0x65, 0x73, + 0x73, 0x61, 0x67, 0x65, 0x5f, 0x63, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, + 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x43, 0x69, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x77, 0x61, + 0x69, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x04, 0x77, 0x61, 0x69, 0x74, 0x22, 0x38, + 0x0a, 0x0e, 0x47, 0x65, 0x74, 0x54, 0x78, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x12, 0x26, 0x0a, 0x03, 0x74, 0x78, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, + 0x61, 0x70, 0x69, 0x2e, 0x73, 0x65, 0x6e, 0x64, 0x66, 0x69, 0x6c, 0x64, 0x2e, 0x70, 0x62, 0x2e, + 0x54, 0x78, 0x6e, 0x52, 0x03, 0x74, 0x78, 0x6e, 0x22, 0x97, 0x07, 0x0a, 0x0f, 0x4c, 0x69, 0x73, + 0x74, 0x54, 0x78, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1f, 0x0a, 0x0b, + 0x66, 0x72, 0x6f, 0x6d, 0x5f, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x0a, 0x66, 0x72, 0x6f, 0x6d, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x12, 0x1b, 0x0a, + 0x09, 0x74, 0x6f, 0x5f, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x08, 0x74, 0x6f, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x12, 0x29, 0x0a, 0x10, 0x69, 0x6e, + 0x76, 0x6f, 0x6c, 0x76, 0x69, 0x6e, 0x67, 0x5f, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x18, 0x03, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x69, 0x6e, 0x76, 0x6f, 0x6c, 0x76, 0x69, 0x6e, 0x67, 0x46, + 0x69, 0x6c, 0x74, 0x65, 0x72, 0x12, 0x38, 0x0a, 0x19, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x5f, + 0x6e, 0x61, 0x6e, 0x6f, 0x5f, 0x66, 0x69, 0x6c, 0x5f, 0x6c, 0x74, 0x5f, 0x66, 0x69, 0x6c, 0x74, + 0x65, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x15, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, + 0x4e, 0x61, 0x6e, 0x6f, 0x46, 0x69, 0x6c, 0x4c, 0x74, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x12, 0x38, 0x0a, 0x19, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x6e, 0x61, 0x6e, 0x6f, 0x5f, 0x66, - 0x69, 0x6c, 0x5f, 0x65, 0x71, 0x5f, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x18, 0x08, 0x20, 0x01, + 0x69, 0x6c, 0x5f, 0x67, 0x74, 0x5f, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, 0x52, 0x15, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x4e, 0x61, 0x6e, 0x6f, 0x46, 0x69, - 0x6c, 0x45, 0x71, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x12, 0x4f, 0x0a, 0x14, 0x6d, 0x65, 0x73, - 0x73, 0x61, 0x67, 0x65, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x5f, 0x66, 0x69, 0x6c, 0x74, 0x65, - 0x72, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1d, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x73, 0x65, - 0x6e, 0x64, 0x66, 0x69, 0x6c, 0x64, 0x2e, 0x70, 0x62, 0x2e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, - 0x65, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x12, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x53, - 0x74, 0x61, 0x74, 0x65, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x12, 0x45, 0x0a, 0x0e, 0x77, 0x61, - 0x69, 0x74, 0x69, 0x6e, 0x67, 0x5f, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x18, 0x0a, 0x20, 0x01, - 0x28, 0x0e, 0x32, 0x1e, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x73, 0x65, 0x6e, 0x64, 0x66, 0x69, 0x6c, - 0x64, 0x2e, 0x70, 0x62, 0x2e, 0x57, 0x61, 0x69, 0x74, 0x69, 0x6e, 0x67, 0x46, 0x69, 0x6c, 0x74, - 0x65, 0x72, 0x52, 0x0d, 0x77, 0x61, 0x69, 0x74, 0x69, 0x6e, 0x67, 0x46, 0x69, 0x6c, 0x74, 0x65, - 0x72, 0x12, 0x41, 0x0a, 0x0e, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x62, 0x65, 0x66, - 0x6f, 0x72, 0x65, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, - 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, - 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x0d, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x42, 0x65, - 0x66, 0x6f, 0x72, 0x65, 0x12, 0x3f, 0x0a, 0x0d, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, - 0x61, 0x66, 0x74, 0x65, 0x72, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, - 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, - 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x0c, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, - 0x41, 0x66, 0x74, 0x65, 0x72, 0x12, 0x41, 0x0a, 0x0e, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, - 0x5f, 0x62, 0x65, 0x66, 0x6f, 0x72, 0x65, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, - 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, - 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x0d, 0x75, 0x70, 0x64, 0x61, 0x74, - 0x65, 0x64, 0x42, 0x65, 0x66, 0x6f, 0x72, 0x65, 0x12, 0x3f, 0x0a, 0x0d, 0x75, 0x70, 0x64, 0x61, - 0x74, 0x65, 0x64, 0x5f, 0x61, 0x66, 0x74, 0x65, 0x72, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x6c, 0x47, 0x74, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x12, 0x3c, 0x0a, 0x1b, 0x61, 0x6d, 0x6f, + 0x75, 0x6e, 0x74, 0x5f, 0x6e, 0x61, 0x6e, 0x6f, 0x5f, 0x66, 0x69, 0x6c, 0x5f, 0x6c, 0x74, 0x65, + 0x71, 0x5f, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x18, 0x06, 0x20, 0x01, 0x28, 0x03, 0x52, 0x17, + 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x4e, 0x61, 0x6e, 0x6f, 0x46, 0x69, 0x6c, 0x4c, 0x74, 0x65, + 0x71, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x12, 0x3c, 0x0a, 0x1b, 0x61, 0x6d, 0x6f, 0x75, 0x6e, + 0x74, 0x5f, 0x6e, 0x61, 0x6e, 0x6f, 0x5f, 0x66, 0x69, 0x6c, 0x5f, 0x67, 0x74, 0x65, 0x71, 0x5f, + 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x18, 0x07, 0x20, 0x01, 0x28, 0x03, 0x52, 0x17, 0x61, 0x6d, + 0x6f, 0x75, 0x6e, 0x74, 0x4e, 0x61, 0x6e, 0x6f, 0x46, 0x69, 0x6c, 0x47, 0x74, 0x65, 0x71, 0x46, + 0x69, 0x6c, 0x74, 0x65, 0x72, 0x12, 0x38, 0x0a, 0x19, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x5f, + 0x6e, 0x61, 0x6e, 0x6f, 0x5f, 0x66, 0x69, 0x6c, 0x5f, 0x65, 0x71, 0x5f, 0x66, 0x69, 0x6c, 0x74, + 0x65, 0x72, 0x18, 0x08, 0x20, 0x01, 0x28, 0x03, 0x52, 0x15, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, + 0x4e, 0x61, 0x6e, 0x6f, 0x46, 0x69, 0x6c, 0x45, 0x71, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x12, + 0x4f, 0x0a, 0x14, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x65, + 0x5f, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1d, 0x2e, + 0x61, 0x70, 0x69, 0x2e, 0x73, 0x65, 0x6e, 0x64, 0x66, 0x69, 0x6c, 0x64, 0x2e, 0x70, 0x62, 0x2e, + 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x12, 0x6d, 0x65, + 0x73, 0x73, 0x61, 0x67, 0x65, 0x53, 0x74, 0x61, 0x74, 0x65, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, + 0x12, 0x45, 0x0a, 0x0e, 0x77, 0x61, 0x69, 0x74, 0x69, 0x6e, 0x67, 0x5f, 0x66, 0x69, 0x6c, 0x74, + 0x65, 0x72, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1e, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x73, + 0x65, 0x6e, 0x64, 0x66, 0x69, 0x6c, 0x64, 0x2e, 0x70, 0x62, 0x2e, 0x57, 0x61, 0x69, 0x74, 0x69, + 0x6e, 0x67, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x52, 0x0d, 0x77, 0x61, 0x69, 0x74, 0x69, 0x6e, + 0x67, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x12, 0x41, 0x0a, 0x0e, 0x63, 0x72, 0x65, 0x61, 0x74, + 0x65, 0x64, 0x5f, 0x62, 0x65, 0x66, 0x6f, 0x72, 0x65, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, - 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x0c, 0x75, 0x70, 0x64, - 0x61, 0x74, 0x65, 0x64, 0x41, 0x66, 0x74, 0x65, 0x72, 0x12, 0x1c, 0x0a, 0x09, 0x61, 0x73, 0x63, - 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x61, 0x73, - 0x63, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x12, 0x1d, 0x0a, 0x0a, 0x6d, 0x6f, 0x72, 0x65, 0x5f, - 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x10, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x6d, 0x6f, 0x72, - 0x65, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x14, 0x0a, 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x18, - 0x11, 0x20, 0x01, 0x28, 0x03, 0x52, 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x22, 0x6f, 0x0a, 0x10, - 0x4c, 0x69, 0x73, 0x74, 0x54, 0x78, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x12, 0x28, 0x0a, 0x04, 0x74, 0x78, 0x6e, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x14, - 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x73, 0x65, 0x6e, 0x64, 0x66, 0x69, 0x6c, 0x64, 0x2e, 0x70, 0x62, - 0x2e, 0x54, 0x78, 0x6e, 0x52, 0x04, 0x74, 0x78, 0x6e, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x6d, 0x6f, - 0x72, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x04, 0x6d, 0x6f, 0x72, 0x65, 0x12, 0x1d, - 0x0a, 0x0a, 0x6d, 0x6f, 0x72, 0x65, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x03, 0x20, 0x01, - 0x28, 0x03, 0x52, 0x09, 0x6d, 0x6f, 0x72, 0x65, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0x76, 0x0a, - 0x0e, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, - 0x30, 0x0a, 0x05, 0x61, 0x66, 0x74, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, - 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, - 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x05, 0x61, 0x66, 0x74, 0x65, - 0x72, 0x12, 0x32, 0x0a, 0x06, 0x62, 0x65, 0x66, 0x6f, 0x72, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x0d, 0x63, 0x72, 0x65, + 0x61, 0x74, 0x65, 0x64, 0x42, 0x65, 0x66, 0x6f, 0x72, 0x65, 0x12, 0x3f, 0x0a, 0x0d, 0x63, 0x72, + 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x66, 0x74, 0x65, 0x72, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x06, 0x62, - 0x65, 0x66, 0x6f, 0x72, 0x65, 0x22, 0xc0, 0x03, 0x0a, 0x0f, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, - 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x63, 0x6f, 0x75, - 0x6e, 0x74, 0x5f, 0x74, 0x78, 0x6e, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x63, - 0x6f, 0x75, 0x6e, 0x74, 0x54, 0x78, 0x6e, 0x73, 0x12, 0x23, 0x0a, 0x0d, 0x63, 0x6f, 0x75, 0x6e, - 0x74, 0x5f, 0x70, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, - 0x0c, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x50, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x12, 0x21, 0x0a, - 0x0c, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x18, 0x03, 0x20, - 0x01, 0x28, 0x03, 0x52, 0x0b, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x41, 0x63, 0x74, 0x69, 0x76, 0x65, - 0x12, 0x21, 0x0a, 0x0c, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x66, 0x61, 0x69, 0x6c, 0x65, 0x64, - 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0b, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x46, 0x61, 0x69, - 0x6c, 0x65, 0x64, 0x12, 0x23, 0x0a, 0x0d, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x77, 0x61, 0x69, - 0x74, 0x69, 0x6e, 0x67, 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0c, 0x63, 0x6f, 0x75, 0x6e, - 0x74, 0x57, 0x61, 0x69, 0x74, 0x69, 0x6e, 0x67, 0x12, 0x28, 0x0a, 0x10, 0x63, 0x6f, 0x75, 0x6e, - 0x74, 0x5f, 0x66, 0x72, 0x6f, 0x6d, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x73, 0x18, 0x06, 0x20, 0x01, - 0x28, 0x03, 0x52, 0x0e, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x46, 0x72, 0x6f, 0x6d, 0x41, 0x64, 0x64, - 0x72, 0x73, 0x12, 0x24, 0x0a, 0x0e, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x74, 0x6f, 0x5f, 0x61, - 0x64, 0x64, 0x72, 0x73, 0x18, 0x07, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0c, 0x63, 0x6f, 0x75, 0x6e, - 0x74, 0x54, 0x6f, 0x41, 0x64, 0x64, 0x72, 0x73, 0x12, 0x2d, 0x0a, 0x13, 0x74, 0x6f, 0x74, 0x61, - 0x6c, 0x5f, 0x6e, 0x61, 0x6e, 0x6f, 0x5f, 0x66, 0x69, 0x6c, 0x5f, 0x73, 0x65, 0x6e, 0x74, 0x18, - 0x08, 0x20, 0x01, 0x28, 0x03, 0x52, 0x10, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x4e, 0x61, 0x6e, 0x6f, - 0x46, 0x69, 0x6c, 0x53, 0x65, 0x6e, 0x74, 0x12, 0x29, 0x0a, 0x11, 0x61, 0x76, 0x67, 0x5f, 0x6e, - 0x61, 0x6e, 0x6f, 0x5f, 0x66, 0x69, 0x6c, 0x5f, 0x73, 0x65, 0x6e, 0x74, 0x18, 0x09, 0x20, 0x01, - 0x28, 0x01, 0x52, 0x0e, 0x61, 0x76, 0x67, 0x4e, 0x61, 0x6e, 0x6f, 0x46, 0x69, 0x6c, 0x53, 0x65, - 0x6e, 0x74, 0x12, 0x29, 0x0a, 0x11, 0x6d, 0x61, 0x78, 0x5f, 0x6e, 0x61, 0x6e, 0x6f, 0x5f, 0x66, - 0x69, 0x6c, 0x5f, 0x73, 0x65, 0x6e, 0x74, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0e, 0x6d, - 0x61, 0x78, 0x4e, 0x61, 0x6e, 0x6f, 0x46, 0x69, 0x6c, 0x53, 0x65, 0x6e, 0x74, 0x12, 0x29, 0x0a, - 0x11, 0x6d, 0x69, 0x6e, 0x5f, 0x6e, 0x61, 0x6e, 0x6f, 0x5f, 0x66, 0x69, 0x6c, 0x5f, 0x73, 0x65, - 0x6e, 0x74, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0e, 0x6d, 0x69, 0x6e, 0x4e, 0x61, 0x6e, - 0x6f, 0x46, 0x69, 0x6c, 0x53, 0x65, 0x6e, 0x74, 0x2a, 0x7c, 0x0a, 0x0c, 0x4d, 0x65, 0x73, 0x73, - 0x61, 0x67, 0x65, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x1d, 0x0a, 0x19, 0x4d, 0x45, 0x53, 0x53, - 0x41, 0x47, 0x45, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, - 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x19, 0x0a, 0x15, 0x4d, 0x45, 0x53, 0x53, 0x41, - 0x47, 0x45, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x45, 0x5f, 0x50, 0x45, 0x4e, 0x44, 0x49, 0x4e, 0x47, - 0x10, 0x01, 0x12, 0x18, 0x0a, 0x14, 0x4d, 0x45, 0x53, 0x53, 0x41, 0x47, 0x45, 0x5f, 0x53, 0x54, - 0x41, 0x54, 0x45, 0x5f, 0x41, 0x43, 0x54, 0x49, 0x56, 0x45, 0x10, 0x02, 0x12, 0x18, 0x0a, 0x14, - 0x4d, 0x45, 0x53, 0x53, 0x41, 0x47, 0x45, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x45, 0x5f, 0x46, 0x41, - 0x49, 0x4c, 0x45, 0x44, 0x10, 0x03, 0x2a, 0x6b, 0x0a, 0x0d, 0x57, 0x61, 0x69, 0x74, 0x69, 0x6e, - 0x67, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x12, 0x1e, 0x0a, 0x1a, 0x57, 0x41, 0x49, 0x54, 0x49, - 0x4e, 0x47, 0x5f, 0x46, 0x49, 0x4c, 0x54, 0x45, 0x52, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, - 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x1a, 0x0a, 0x16, 0x57, 0x41, 0x49, 0x54, 0x49, - 0x4e, 0x47, 0x5f, 0x46, 0x49, 0x4c, 0x54, 0x45, 0x52, 0x5f, 0x57, 0x41, 0x49, 0x54, 0x49, 0x4e, - 0x47, 0x10, 0x01, 0x12, 0x1e, 0x0a, 0x1a, 0x57, 0x41, 0x49, 0x54, 0x49, 0x4e, 0x47, 0x5f, 0x46, - 0x49, 0x4c, 0x54, 0x45, 0x52, 0x5f, 0x4e, 0x4f, 0x54, 0x5f, 0x57, 0x41, 0x49, 0x54, 0x49, 0x4e, - 0x47, 0x10, 0x02, 0x32, 0xc7, 0x02, 0x0a, 0x0e, 0x53, 0x65, 0x6e, 0x64, 0x46, 0x69, 0x6c, 0x53, - 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x4e, 0x0a, 0x07, 0x53, 0x65, 0x6e, 0x64, 0x46, 0x69, - 0x6c, 0x12, 0x1f, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x73, 0x65, 0x6e, 0x64, 0x66, 0x69, 0x6c, 0x64, - 0x2e, 0x70, 0x62, 0x2e, 0x53, 0x65, 0x6e, 0x64, 0x46, 0x69, 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x1a, 0x20, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x73, 0x65, 0x6e, 0x64, 0x66, 0x69, 0x6c, - 0x64, 0x2e, 0x70, 0x62, 0x2e, 0x53, 0x65, 0x6e, 0x64, 0x46, 0x69, 0x6c, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x42, 0x0a, 0x03, 0x54, 0x78, 0x6e, 0x12, 0x1b, 0x2e, - 0x61, 0x70, 0x69, 0x2e, 0x73, 0x65, 0x6e, 0x64, 0x66, 0x69, 0x6c, 0x64, 0x2e, 0x70, 0x62, 0x2e, - 0x54, 0x78, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1c, 0x2e, 0x61, 0x70, 0x69, - 0x2e, 0x73, 0x65, 0x6e, 0x64, 0x66, 0x69, 0x6c, 0x64, 0x2e, 0x70, 0x62, 0x2e, 0x54, 0x78, 0x6e, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x51, 0x0a, 0x08, 0x4c, 0x69, - 0x73, 0x74, 0x54, 0x78, 0x6e, 0x73, 0x12, 0x20, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x73, 0x65, 0x6e, - 0x64, 0x66, 0x69, 0x6c, 0x64, 0x2e, 0x70, 0x62, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x54, 0x78, 0x6e, - 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x21, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x73, - 0x65, 0x6e, 0x64, 0x66, 0x69, 0x6c, 0x64, 0x2e, 0x70, 0x62, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x54, - 0x78, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x4e, 0x0a, - 0x07, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x12, 0x1f, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x73, + 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x0c, 0x63, + 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x41, 0x66, 0x74, 0x65, 0x72, 0x12, 0x41, 0x0a, 0x0e, 0x75, + 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x62, 0x65, 0x66, 0x6f, 0x72, 0x65, 0x18, 0x0d, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, + 0x0d, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x42, 0x65, 0x66, 0x6f, 0x72, 0x65, 0x12, 0x3f, + 0x0a, 0x0d, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x66, 0x74, 0x65, 0x72, 0x18, + 0x0e, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, + 0x70, 0x52, 0x0c, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x41, 0x66, 0x74, 0x65, 0x72, 0x12, + 0x1c, 0x0a, 0x09, 0x61, 0x73, 0x63, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x18, 0x0f, 0x20, 0x01, + 0x28, 0x08, 0x52, 0x09, 0x61, 0x73, 0x63, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x12, 0x1d, 0x0a, + 0x0a, 0x6d, 0x6f, 0x72, 0x65, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x10, 0x20, 0x01, 0x28, + 0x03, 0x52, 0x09, 0x6d, 0x6f, 0x72, 0x65, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x14, 0x0a, 0x05, + 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x18, 0x11, 0x20, 0x01, 0x28, 0x03, 0x52, 0x05, 0x6c, 0x69, 0x6d, + 0x69, 0x74, 0x22, 0x6f, 0x0a, 0x10, 0x4c, 0x69, 0x73, 0x74, 0x54, 0x78, 0x6e, 0x73, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x28, 0x0a, 0x04, 0x74, 0x78, 0x6e, 0x73, 0x18, 0x01, + 0x20, 0x03, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x73, 0x65, 0x6e, 0x64, 0x66, + 0x69, 0x6c, 0x64, 0x2e, 0x70, 0x62, 0x2e, 0x54, 0x78, 0x6e, 0x52, 0x04, 0x74, 0x78, 0x6e, 0x73, + 0x12, 0x12, 0x0a, 0x04, 0x6d, 0x6f, 0x72, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x04, + 0x6d, 0x6f, 0x72, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x6d, 0x6f, 0x72, 0x65, 0x5f, 0x74, 0x6f, 0x6b, + 0x65, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x6d, 0x6f, 0x72, 0x65, 0x54, 0x6f, + 0x6b, 0x65, 0x6e, 0x22, 0x76, 0x0a, 0x0e, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x30, 0x0a, 0x05, 0x61, 0x66, 0x74, 0x65, 0x72, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, + 0x52, 0x05, 0x61, 0x66, 0x74, 0x65, 0x72, 0x12, 0x32, 0x0a, 0x06, 0x62, 0x65, 0x66, 0x6f, 0x72, + 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, + 0x61, 0x6d, 0x70, 0x52, 0x06, 0x62, 0x65, 0x66, 0x6f, 0x72, 0x65, 0x22, 0xc0, 0x03, 0x0a, 0x0f, + 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, + 0x1d, 0x0a, 0x0a, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x74, 0x78, 0x6e, 0x73, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x03, 0x52, 0x09, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x54, 0x78, 0x6e, 0x73, 0x12, 0x23, + 0x0a, 0x0d, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x70, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0c, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x50, 0x65, 0x6e, 0x64, + 0x69, 0x6e, 0x67, 0x12, 0x21, 0x0a, 0x0c, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x61, 0x63, 0x74, + 0x69, 0x76, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0b, 0x63, 0x6f, 0x75, 0x6e, 0x74, + 0x41, 0x63, 0x74, 0x69, 0x76, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x5f, + 0x66, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0b, 0x63, 0x6f, + 0x75, 0x6e, 0x74, 0x46, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x12, 0x23, 0x0a, 0x0d, 0x63, 0x6f, 0x75, + 0x6e, 0x74, 0x5f, 0x77, 0x61, 0x69, 0x74, 0x69, 0x6e, 0x67, 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, + 0x52, 0x0c, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x57, 0x61, 0x69, 0x74, 0x69, 0x6e, 0x67, 0x12, 0x28, + 0x0a, 0x10, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x66, 0x72, 0x6f, 0x6d, 0x5f, 0x61, 0x64, 0x64, + 0x72, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0e, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x46, + 0x72, 0x6f, 0x6d, 0x41, 0x64, 0x64, 0x72, 0x73, 0x12, 0x24, 0x0a, 0x0e, 0x63, 0x6f, 0x75, 0x6e, + 0x74, 0x5f, 0x74, 0x6f, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x73, 0x18, 0x07, 0x20, 0x01, 0x28, 0x03, + 0x52, 0x0c, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x54, 0x6f, 0x41, 0x64, 0x64, 0x72, 0x73, 0x12, 0x2d, + 0x0a, 0x13, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x6e, 0x61, 0x6e, 0x6f, 0x5f, 0x66, 0x69, 0x6c, + 0x5f, 0x73, 0x65, 0x6e, 0x74, 0x18, 0x08, 0x20, 0x01, 0x28, 0x03, 0x52, 0x10, 0x74, 0x6f, 0x74, + 0x61, 0x6c, 0x4e, 0x61, 0x6e, 0x6f, 0x46, 0x69, 0x6c, 0x53, 0x65, 0x6e, 0x74, 0x12, 0x29, 0x0a, + 0x11, 0x61, 0x76, 0x67, 0x5f, 0x6e, 0x61, 0x6e, 0x6f, 0x5f, 0x66, 0x69, 0x6c, 0x5f, 0x73, 0x65, + 0x6e, 0x74, 0x18, 0x09, 0x20, 0x01, 0x28, 0x01, 0x52, 0x0e, 0x61, 0x76, 0x67, 0x4e, 0x61, 0x6e, + 0x6f, 0x46, 0x69, 0x6c, 0x53, 0x65, 0x6e, 0x74, 0x12, 0x29, 0x0a, 0x11, 0x6d, 0x61, 0x78, 0x5f, + 0x6e, 0x61, 0x6e, 0x6f, 0x5f, 0x66, 0x69, 0x6c, 0x5f, 0x73, 0x65, 0x6e, 0x74, 0x18, 0x0a, 0x20, + 0x01, 0x28, 0x03, 0x52, 0x0e, 0x6d, 0x61, 0x78, 0x4e, 0x61, 0x6e, 0x6f, 0x46, 0x69, 0x6c, 0x53, + 0x65, 0x6e, 0x74, 0x12, 0x29, 0x0a, 0x11, 0x6d, 0x69, 0x6e, 0x5f, 0x6e, 0x61, 0x6e, 0x6f, 0x5f, + 0x66, 0x69, 0x6c, 0x5f, 0x73, 0x65, 0x6e, 0x74, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0e, + 0x6d, 0x69, 0x6e, 0x4e, 0x61, 0x6e, 0x6f, 0x46, 0x69, 0x6c, 0x53, 0x65, 0x6e, 0x74, 0x2a, 0x7c, + 0x0a, 0x0c, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x1d, + 0x0a, 0x19, 0x4d, 0x45, 0x53, 0x53, 0x41, 0x47, 0x45, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x45, 0x5f, + 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x19, 0x0a, + 0x15, 0x4d, 0x45, 0x53, 0x53, 0x41, 0x47, 0x45, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x45, 0x5f, 0x50, + 0x45, 0x4e, 0x44, 0x49, 0x4e, 0x47, 0x10, 0x01, 0x12, 0x18, 0x0a, 0x14, 0x4d, 0x45, 0x53, 0x53, + 0x41, 0x47, 0x45, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x45, 0x5f, 0x41, 0x43, 0x54, 0x49, 0x56, 0x45, + 0x10, 0x02, 0x12, 0x18, 0x0a, 0x14, 0x4d, 0x45, 0x53, 0x53, 0x41, 0x47, 0x45, 0x5f, 0x53, 0x54, + 0x41, 0x54, 0x45, 0x5f, 0x46, 0x41, 0x49, 0x4c, 0x45, 0x44, 0x10, 0x03, 0x2a, 0x6b, 0x0a, 0x0d, + 0x57, 0x61, 0x69, 0x74, 0x69, 0x6e, 0x67, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x12, 0x1e, 0x0a, + 0x1a, 0x57, 0x41, 0x49, 0x54, 0x49, 0x4e, 0x47, 0x5f, 0x46, 0x49, 0x4c, 0x54, 0x45, 0x52, 0x5f, + 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x1a, 0x0a, + 0x16, 0x57, 0x41, 0x49, 0x54, 0x49, 0x4e, 0x47, 0x5f, 0x46, 0x49, 0x4c, 0x54, 0x45, 0x52, 0x5f, + 0x57, 0x41, 0x49, 0x54, 0x49, 0x4e, 0x47, 0x10, 0x01, 0x12, 0x1e, 0x0a, 0x1a, 0x57, 0x41, 0x49, + 0x54, 0x49, 0x4e, 0x47, 0x5f, 0x46, 0x49, 0x4c, 0x54, 0x45, 0x52, 0x5f, 0x4e, 0x4f, 0x54, 0x5f, + 0x57, 0x41, 0x49, 0x54, 0x49, 0x4e, 0x47, 0x10, 0x02, 0x32, 0xd0, 0x02, 0x0a, 0x0e, 0x53, 0x65, + 0x6e, 0x64, 0x46, 0x69, 0x6c, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x4e, 0x0a, 0x07, + 0x53, 0x65, 0x6e, 0x64, 0x46, 0x69, 0x6c, 0x12, 0x1f, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x73, 0x65, + 0x6e, 0x64, 0x66, 0x69, 0x6c, 0x64, 0x2e, 0x70, 0x62, 0x2e, 0x53, 0x65, 0x6e, 0x64, 0x46, 0x69, + 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x20, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x73, + 0x65, 0x6e, 0x64, 0x66, 0x69, 0x6c, 0x64, 0x2e, 0x70, 0x62, 0x2e, 0x53, 0x65, 0x6e, 0x64, 0x46, + 0x69, 0x6c, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x4b, 0x0a, 0x06, + 0x47, 0x65, 0x74, 0x54, 0x78, 0x6e, 0x12, 0x1e, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x73, 0x65, 0x6e, + 0x64, 0x66, 0x69, 0x6c, 0x64, 0x2e, 0x70, 0x62, 0x2e, 0x47, 0x65, 0x74, 0x54, 0x78, 0x6e, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x73, 0x65, 0x6e, + 0x64, 0x66, 0x69, 0x6c, 0x64, 0x2e, 0x70, 0x62, 0x2e, 0x47, 0x65, 0x74, 0x54, 0x78, 0x6e, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x51, 0x0a, 0x08, 0x4c, 0x69, 0x73, + 0x74, 0x54, 0x78, 0x6e, 0x73, 0x12, 0x20, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x73, 0x65, 0x6e, 0x64, + 0x66, 0x69, 0x6c, 0x64, 0x2e, 0x70, 0x62, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x54, 0x78, 0x6e, 0x73, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x21, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x73, 0x65, + 0x6e, 0x64, 0x66, 0x69, 0x6c, 0x64, 0x2e, 0x70, 0x62, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x54, 0x78, + 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x4e, 0x0a, 0x07, + 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x12, 0x1f, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x73, 0x65, + 0x6e, 0x64, 0x66, 0x69, 0x6c, 0x64, 0x2e, 0x70, 0x62, 0x2e, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, + 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x20, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x73, 0x65, 0x6e, 0x64, 0x66, 0x69, 0x6c, 0x64, 0x2e, 0x70, 0x62, 0x2e, 0x53, 0x75, 0x6d, 0x6d, 0x61, - 0x72, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x20, 0x2e, 0x61, 0x70, 0x69, 0x2e, - 0x73, 0x65, 0x6e, 0x64, 0x66, 0x69, 0x6c, 0x64, 0x2e, 0x70, 0x62, 0x2e, 0x53, 0x75, 0x6d, 0x6d, - 0x61, 0x72, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x42, 0x31, 0x5a, - 0x2f, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x74, 0x65, 0x78, 0x74, - 0x69, 0x6c, 0x65, 0x69, 0x6f, 0x2f, 0x74, 0x65, 0x78, 0x74, 0x69, 0x6c, 0x65, 0x2f, 0x76, 0x32, - 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x73, 0x65, 0x6e, 0x64, 0x66, 0x69, 0x6c, 0x64, 0x2f, 0x70, 0x62, - 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x72, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x42, 0x31, 0x5a, 0x2f, + 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x74, 0x65, 0x78, 0x74, 0x69, + 0x6c, 0x65, 0x69, 0x6f, 0x2f, 0x74, 0x65, 0x78, 0x74, 0x69, 0x6c, 0x65, 0x2f, 0x76, 0x32, 0x2f, + 0x61, 0x70, 0x69, 0x2f, 0x73, 0x65, 0x6e, 0x64, 0x66, 0x69, 0x6c, 0x64, 0x2f, 0x70, 0x62, 0x62, + 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -1102,8 +1103,8 @@ var file_api_sendfild_pb_sendfil_proto_goTypes = []interface{}{ (*Txn)(nil), // 2: api.sendfild.pb.Txn (*SendFilRequest)(nil), // 3: api.sendfild.pb.SendFilRequest (*SendFilResponse)(nil), // 4: api.sendfild.pb.SendFilResponse - (*TxnRequest)(nil), // 5: api.sendfild.pb.TxnRequest - (*TxnResponse)(nil), // 6: api.sendfild.pb.TxnResponse + (*GetTxnRequest)(nil), // 5: api.sendfild.pb.GetTxnRequest + (*GetTxnResponse)(nil), // 6: api.sendfild.pb.GetTxnResponse (*ListTxnsRequest)(nil), // 7: api.sendfild.pb.ListTxnsRequest (*ListTxnsResponse)(nil), // 8: api.sendfild.pb.ListTxnsResponse (*SummaryRequest)(nil), // 9: api.sendfild.pb.SummaryRequest @@ -1115,7 +1116,7 @@ var file_api_sendfild_pb_sendfil_proto_depIdxs = []int32{ 11, // 1: api.sendfild.pb.Txn.created_at:type_name -> google.protobuf.Timestamp 11, // 2: api.sendfild.pb.Txn.updated_at:type_name -> google.protobuf.Timestamp 2, // 3: api.sendfild.pb.SendFilResponse.txn:type_name -> api.sendfild.pb.Txn - 2, // 4: api.sendfild.pb.TxnResponse.txn:type_name -> api.sendfild.pb.Txn + 2, // 4: api.sendfild.pb.GetTxnResponse.txn:type_name -> api.sendfild.pb.Txn 0, // 5: api.sendfild.pb.ListTxnsRequest.message_state_filter:type_name -> api.sendfild.pb.MessageState 1, // 6: api.sendfild.pb.ListTxnsRequest.waiting_filter:type_name -> api.sendfild.pb.WaitingFilter 11, // 7: api.sendfild.pb.ListTxnsRequest.created_before:type_name -> google.protobuf.Timestamp @@ -1126,11 +1127,11 @@ var file_api_sendfild_pb_sendfil_proto_depIdxs = []int32{ 11, // 12: api.sendfild.pb.SummaryRequest.after:type_name -> google.protobuf.Timestamp 11, // 13: api.sendfild.pb.SummaryRequest.before:type_name -> google.protobuf.Timestamp 3, // 14: api.sendfild.pb.SendFilService.SendFil:input_type -> api.sendfild.pb.SendFilRequest - 5, // 15: api.sendfild.pb.SendFilService.Txn:input_type -> api.sendfild.pb.TxnRequest + 5, // 15: api.sendfild.pb.SendFilService.GetTxn:input_type -> api.sendfild.pb.GetTxnRequest 7, // 16: api.sendfild.pb.SendFilService.ListTxns:input_type -> api.sendfild.pb.ListTxnsRequest 9, // 17: api.sendfild.pb.SendFilService.Summary:input_type -> api.sendfild.pb.SummaryRequest 4, // 18: api.sendfild.pb.SendFilService.SendFil:output_type -> api.sendfild.pb.SendFilResponse - 6, // 19: api.sendfild.pb.SendFilService.Txn:output_type -> api.sendfild.pb.TxnResponse + 6, // 19: api.sendfild.pb.SendFilService.GetTxn:output_type -> api.sendfild.pb.GetTxnResponse 8, // 20: api.sendfild.pb.SendFilService.ListTxns:output_type -> api.sendfild.pb.ListTxnsResponse 10, // 21: api.sendfild.pb.SendFilService.Summary:output_type -> api.sendfild.pb.SummaryResponse 18, // [18:22] is the sub-list for method output_type @@ -1183,7 +1184,7 @@ func file_api_sendfild_pb_sendfil_proto_init() { } } file_api_sendfild_pb_sendfil_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*TxnRequest); i { + switch v := v.(*GetTxnRequest); i { case 0: return &v.state case 1: @@ -1195,7 +1196,7 @@ func file_api_sendfild_pb_sendfil_proto_init() { } } file_api_sendfild_pb_sendfil_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*TxnResponse); i { + switch v := v.(*GetTxnResponse); i { case 0: return &v.state case 1: @@ -1289,7 +1290,7 @@ const _ = grpc.SupportPackageIsVersion6 // For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. type SendFilServiceClient interface { SendFil(ctx context.Context, in *SendFilRequest, opts ...grpc.CallOption) (*SendFilResponse, error) - Txn(ctx context.Context, in *TxnRequest, opts ...grpc.CallOption) (*TxnResponse, error) + GetTxn(ctx context.Context, in *GetTxnRequest, opts ...grpc.CallOption) (*GetTxnResponse, error) ListTxns(ctx context.Context, in *ListTxnsRequest, opts ...grpc.CallOption) (*ListTxnsResponse, error) Summary(ctx context.Context, in *SummaryRequest, opts ...grpc.CallOption) (*SummaryResponse, error) } @@ -1311,9 +1312,9 @@ func (c *sendFilServiceClient) SendFil(ctx context.Context, in *SendFilRequest, return out, nil } -func (c *sendFilServiceClient) Txn(ctx context.Context, in *TxnRequest, opts ...grpc.CallOption) (*TxnResponse, error) { - out := new(TxnResponse) - err := c.cc.Invoke(ctx, "/api.sendfild.pb.SendFilService/Txn", in, out, opts...) +func (c *sendFilServiceClient) GetTxn(ctx context.Context, in *GetTxnRequest, opts ...grpc.CallOption) (*GetTxnResponse, error) { + out := new(GetTxnResponse) + err := c.cc.Invoke(ctx, "/api.sendfild.pb.SendFilService/GetTxn", in, out, opts...) if err != nil { return nil, err } @@ -1341,7 +1342,7 @@ func (c *sendFilServiceClient) Summary(ctx context.Context, in *SummaryRequest, // SendFilServiceServer is the server API for SendFilService service. type SendFilServiceServer interface { SendFil(context.Context, *SendFilRequest) (*SendFilResponse, error) - Txn(context.Context, *TxnRequest) (*TxnResponse, error) + GetTxn(context.Context, *GetTxnRequest) (*GetTxnResponse, error) ListTxns(context.Context, *ListTxnsRequest) (*ListTxnsResponse, error) Summary(context.Context, *SummaryRequest) (*SummaryResponse, error) } @@ -1353,8 +1354,8 @@ type UnimplementedSendFilServiceServer struct { func (*UnimplementedSendFilServiceServer) SendFil(context.Context, *SendFilRequest) (*SendFilResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method SendFil not implemented") } -func (*UnimplementedSendFilServiceServer) Txn(context.Context, *TxnRequest) (*TxnResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method Txn not implemented") +func (*UnimplementedSendFilServiceServer) GetTxn(context.Context, *GetTxnRequest) (*GetTxnResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetTxn not implemented") } func (*UnimplementedSendFilServiceServer) ListTxns(context.Context, *ListTxnsRequest) (*ListTxnsResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method ListTxns not implemented") @@ -1385,20 +1386,20 @@ func _SendFilService_SendFil_Handler(srv interface{}, ctx context.Context, dec f return interceptor(ctx, in, info, handler) } -func _SendFilService_Txn_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(TxnRequest) +func _SendFilService_GetTxn_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GetTxnRequest) if err := dec(in); err != nil { return nil, err } if interceptor == nil { - return srv.(SendFilServiceServer).Txn(ctx, in) + return srv.(SendFilServiceServer).GetTxn(ctx, in) } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/api.sendfild.pb.SendFilService/Txn", + FullMethod: "/api.sendfild.pb.SendFilService/GetTxn", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(SendFilServiceServer).Txn(ctx, req.(*TxnRequest)) + return srv.(SendFilServiceServer).GetTxn(ctx, req.(*GetTxnRequest)) } return interceptor(ctx, in, info, handler) } @@ -1448,8 +1449,8 @@ var _SendFilService_serviceDesc = grpc.ServiceDesc{ Handler: _SendFilService_SendFil_Handler, }, { - MethodName: "Txn", - Handler: _SendFilService_Txn_Handler, + MethodName: "GetTxn", + Handler: _SendFilService_GetTxn_Handler, }, { MethodName: "ListTxns", diff --git a/api/sendfild/pb/sendfil.proto b/api/sendfild/pb/sendfil.proto index aace918f1..913d90292 100644 --- a/api/sendfild/pb/sendfil.proto +++ b/api/sendfild/pb/sendfil.proto @@ -41,12 +41,12 @@ message SendFilResponse { Txn txn = 1; } -message TxnRequest { +message GetTxnRequest { string message_cid = 1; bool wait = 2; } -message TxnResponse { +message GetTxnResponse { Txn txn = 1; } @@ -97,7 +97,7 @@ message SummaryResponse { service SendFilService { rpc SendFil(SendFilRequest) returns (SendFilResponse) {} - rpc Txn(TxnRequest) returns (TxnResponse) {} + rpc GetTxn(GetTxnRequest) returns (GetTxnResponse) {} rpc ListTxns(ListTxnsRequest) returns (ListTxnsResponse) {} rpc Summary(SummaryRequest) returns (SummaryResponse) {} } \ No newline at end of file diff --git a/api/sendfild/service/service.go b/api/sendfild/service/service.go index ed41f9b02..7867edca2 100644 --- a/api/sendfild/service/service.go +++ b/api/sendfild/service/service.go @@ -261,7 +261,7 @@ func (s *Service) SendFil(ctx context.Context, req *pb.SendFilRequest) (*pb.Send return &pb.SendFilResponse{Txn: pbTx}, nil } -func (s *Service) Txn(ctx context.Context, req *pb.TxnRequest) (*pb.TxnResponse, error) { +func (s *Service) GetTxn(ctx context.Context, req *pb.GetTxnRequest) (*pb.GetTxnResponse, error) { res := s.col.FindOne(ctx, bson.M{"message_cids.cid": req.MessageCid}) if res.Err() == mongo.ErrNoDocuments { return nil, status.Error(codes.NotFound, "no txn found for cid") @@ -288,7 +288,7 @@ func (s *Service) Txn(ctx context.Context, req *pb.TxnRequest) (*pb.TxnResponse, return nil, status.Errorf(codes.Internal, "converting to pb txn: %v", err) } - return &pb.TxnResponse{Txn: pbTx}, nil + return &pb.GetTxnResponse{Txn: pbTx}, nil } func (s *Service) ListTxns(ctx context.Context, req *pb.ListTxnsRequest) (*pb.ListTxnsResponse, error) { diff --git a/api/sendfild/service/service_test.go b/api/sendfild/service/service_test.go index de115a552..b68fc6136 100644 --- a/api/sendfild/service/service_test.go +++ b/api/sendfild/service/service_test.go @@ -92,32 +92,32 @@ func TestSendFilWait(t *testing.T) { require.Equal(t, pb.MessageState_MESSAGE_STATE_ACTIVE, txn.MessageState) } -func TestTxn(t *testing.T) { +func TestGetTxn(t *testing.T) { c, lc, dAddr, cleanup := requireSetup(t, ctx, setupWithSpeed(1000)) defer cleanup() addr := requireLotusAddress(t, ctx, lc) txn := requireSendFil(t, ctx, c, dAddr.String(), addr.String(), oneFil, false) - res, err := c.Txn(ctx, &pb.TxnRequest{MessageCid: txn.MessageCid, Wait: false}) + res, err := c.GetTxn(ctx, &pb.GetTxnRequest{MessageCid: txn.MessageCid, Wait: false}) require.NoError(t, err) require.Equal(t, txn.MessageCid, res.Txn.MessageCid) require.Equal(t, pb.MessageState_MESSAGE_STATE_PENDING, res.Txn.MessageState) } -func TestTxnWait(t *testing.T) { +func TestGetTxnWait(t *testing.T) { c, lc, dAddr, cleanup := requireSetup(t, ctx) defer cleanup() addr := requireLotusAddress(t, ctx, lc) txn1 := requireSendFil(t, ctx, c, dAddr.String(), addr.String(), oneFil, false) - res, err := c.Txn(ctx, &pb.TxnRequest{MessageCid: txn1.MessageCid, Wait: true}) + res, err := c.GetTxn(ctx, &pb.GetTxnRequest{MessageCid: txn1.MessageCid, Wait: true}) require.NoError(t, err) require.Equal(t, txn1.MessageCid, res.Txn.MessageCid) require.Equal(t, pb.MessageState_MESSAGE_STATE_ACTIVE, res.Txn.MessageState) } -func TestTxnNonExistent(t *testing.T) { +func TestGetTxnNonExistent(t *testing.T) { c, _, _, cleanup := requireSetup(t, ctx) defer cleanup() - _, err := c.Txn(ctx, &pb.TxnRequest{MessageCid: randomCid().String()}) + _, err := c.GetTxn(ctx, &pb.GetTxnRequest{MessageCid: randomCid().String()}) require.Equal(t, codes.NotFound, status.Code(err)) } From 1d9152ae65264dceb87c03102fa918ab24f89009 Mon Sep 17 00:00:00 2001 From: Aaron Sutula Date: Mon, 8 Mar 2021 11:34:28 -0600 Subject: [PATCH 13/16] unbind ticker Signed-off-by: Aaron Sutula --- api/sendfild/service/service.go | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/api/sendfild/service/service.go b/api/sendfild/service/service.go index 7867edca2..0b75aa8ad 100644 --- a/api/sendfild/service/service.go +++ b/api/sendfild/service/service.go @@ -152,9 +152,9 @@ func New(config Config) (*Service, error) { } }() - if err := s.waitAllQualifying(ctx, true); err != nil { + if err := s.waitAllPending(ctx, true); err != nil { cancel() - return nil, fmt.Errorf("calling waitAllQualifying: %v", err) + return nil, fmt.Errorf("calling waitAllPending: %v", err) } s.bindTicker(ctx) @@ -162,11 +162,8 @@ func New(config Config) (*Service, error) { return s, nil } -func (s *Service) waitAllQualifying(ctx context.Context, isInitialRun bool) error { - filter := bson.M{"$and": bson.A{ - bson.M{"message_state": bson.M{"$ne": pb.MessageState_MESSAGE_STATE_ACTIVE}}, - bson.M{"message_state": bson.M{"$ne": pb.MessageState_MESSAGE_STATE_FAILED}}, - }} +func (s *Service) waitAllPending(ctx context.Context, isInitialRun bool) error { + filter := bson.M{"message_state": pb.MessageState_MESSAGE_STATE_PENDING} if !isInitialRun { filter["waiting"] = false } @@ -190,9 +187,14 @@ func (s *Service) waitAllQualifying(ctx context.Context, isInitialRun bool) erro func (s *Service) bindTicker(ctx context.Context) { go func() { for { - <-s.ticker.C - if err := s.waitAllQualifying(ctx, false); err != nil { - log.Errorf("waitAllQualifying from ticker: %v", err) + select { + case <-s.ticker.C: + if err := s.waitAllPending(ctx, false); err != nil { + log.Errorf("waitAllPending from ticker: %v", err) + } + case <-ctx.Done(): + log.Info("unbinding ticker") + return } } }() From 32f8352c0582647387cca6bb42359bd2d0baf068 Mon Sep 17 00:00:00 2001 From: Aaron Sutula Date: Mon, 8 Mar 2021 11:49:54 -0600 Subject: [PATCH 14/16] findopts sugar Signed-off-by: Aaron Sutula --- api/filrewardsd/service/service.go | 11 +++++------ api/sendfild/service/service.go | 7 ++++--- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/api/filrewardsd/service/service.go b/api/filrewardsd/service/service.go index 1409d007c..1c2c1f3a0 100644 --- a/api/filrewardsd/service/service.go +++ b/api/filrewardsd/service/service.go @@ -162,8 +162,7 @@ func New(config Config) (*Service, error) { } // Populate caches. - opts := options.Find() - cursor, err := rewardsCol.Find(ctx, bson.M{}, opts) + cursor, err := rewardsCol.Find(ctx, bson.M{}, options.Find()) if err != nil { cancel() return nil, fmt.Errorf("querying RewardRecords to populate cache: %s", err) @@ -307,13 +306,13 @@ func (s *Service) ProcessAnalyticsEvent(ctx context.Context, req *pb.ProcessAnal func (s *Service) ListRewards(ctx context.Context, req *pb.ListRewardsRequest) (*pb.ListRewardsResponse, error) { findOpts := options.Find() if req.Limit > 0 { - findOpts.Limit = &req.Limit + findOpts = findOpts.SetLimit(req.Limit) } sort := -1 if req.Ascending { sort = 1 } - findOpts.Sort = bson.D{primitive.E{Key: "created_at", Value: sort}} + findOpts = findOpts.SetSort(bson.D{primitive.E{Key: "created_at", Value: sort}}) filter := bson.M{} if req.OrgKeyFilter != "" { filter["org_key"] = req.OrgKeyFilter @@ -480,13 +479,13 @@ func (s *Service) FinalizeClaim(ctx context.Context, req *pb.FinalizeClaimReques func (s *Service) ListClaims(ctx context.Context, req *pb.ListClaimsRequest) (*pb.ListClaimsResponse, error) { findOpts := options.Find() if req.Limit > 0 { - findOpts.Limit = &req.Limit + findOpts = findOpts.SetLimit(req.Limit) } sort := -1 if req.Ascending { sort = 1 } - findOpts.Sort = bson.D{primitive.E{Key: "created_at", Value: sort}} + findOpts = findOpts.SetSort(bson.D{primitive.E{Key: "created_at", Value: sort}}) filter := bson.M{} if req.OrgKeyFilter != "" { filter["org_key"] = req.OrgKeyFilter diff --git a/api/sendfild/service/service.go b/api/sendfild/service/service.go index 0b75aa8ad..f8b82cce7 100644 --- a/api/sendfild/service/service.go +++ b/api/sendfild/service/service.go @@ -277,7 +277,7 @@ func (s *Service) GetTxn(ctx context.Context, req *pb.GetTxnRequest) (*pb.GetTxn return nil, status.Errorf(codes.Internal, "decoding cid txn result: %v", res.Err()) } - if tx.MessageState != pb.MessageState_MESSAGE_STATE_ACTIVE && tx.MessageState != pb.MessageState_MESSAGE_STATE_FAILED && req.Wait { + if tx.MessageState == pb.MessageState_MESSAGE_STATE_PENDING && req.Wait { res := <-s.wait(tx) if res.err != nil { return nil, status.Errorf(codes.Internal, "waiting for result: %v", res.err) @@ -296,13 +296,14 @@ func (s *Service) GetTxn(ctx context.Context, req *pb.GetTxnRequest) (*pb.GetTxn func (s *Service) ListTxns(ctx context.Context, req *pb.ListTxnsRequest) (*pb.ListTxnsResponse, error) { findOpts := options.Find() if req.Limit > 0 { - findOpts.Limit = &req.Limit + findOpts = findOpts.SetLimit(req.Limit) } sort := -1 if req.Ascending { sort = 1 } - findOpts.Sort = bson.D{primitive.E{Key: "created_at", Value: sort}} + findOpts = findOpts.SetSort(bson.D{primitive.E{Key: "created_at", Value: sort}}) + filter := bson.M{} // Involving/from/to From dc078338aff222d8a80929f01abfe8adcacf17c8 Mon Sep 17 00:00:00 2001 From: Aaron Sutula Date: Mon, 8 Mar 2021 12:29:09 -0600 Subject: [PATCH 15/16] log error for unexpected cid problems Signed-off-by: Aaron Sutula --- api/sendfild/service/service.go | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/api/sendfild/service/service.go b/api/sendfild/service/service.go index f8b82cce7..2bbf79611 100644 --- a/api/sendfild/service/service.go +++ b/api/sendfild/service/service.go @@ -56,6 +56,7 @@ type txn struct { func (t txn) latestMsgCid() (msgCid, error) { if len(t.MessageCids) == 0 { + log.Errorf("no message cid found for txn object id %v", t.ID.Hex()) return msgCid{}, fmt.Errorf("no message cids found") } return t.MessageCids[len(t.MessageCids)-1], nil @@ -556,6 +557,7 @@ func (s *Service) wait(tx txn) chan waitResult { cancel() }() if err != nil { + log.Errorf("creating lotus client: %v", err) ch <- waitResult{err: fmt.Errorf("creating lotus client: %v", err)} return } @@ -565,7 +567,6 @@ func (s *Service) wait(tx txn) chan waitResult { tx.MessageState = pb.MessageState_MESSAGE_STATE_FAILED tx.FailureMsg = fmt.Sprintf("getting latest message cid from txn: %v", err) tx.UpdatedAt = time.Now() - log.Warnf("failing txn with err: %s", tx.FailureMsg) if err := s.updateTxn(ctx, tx); err != nil { ch <- waitResult{err: err} return @@ -575,10 +576,10 @@ func (s *Service) wait(tx txn) chan waitResult { } c, err := cid.Decode(lastestMsgCid.Cid) if err != nil { + log.Errorf("decoding message cid: %s", tx.FailureMsg) tx.MessageState = pb.MessageState_MESSAGE_STATE_FAILED tx.FailureMsg = fmt.Sprintf("decoding latest message cid for txn: %v", err) tx.UpdatedAt = time.Now() - log.Warnf("failing txn with err: %s", tx.FailureMsg) if err := s.updateTxn(ctx, tx); err != nil { ch <- waitResult{err: err} return From 6ef1ad75b55321a642bb352889cea7b044483c72 Mon Sep 17 00:00:00 2001 From: Aaron Sutula Date: Mon, 8 Mar 2021 16:20:26 -0600 Subject: [PATCH 16/16] involving address naming Signed-off-by: Aaron Sutula --- api/sendfild/client/client.go | 4 +- api/sendfild/pb/sendfil.pb.go | 273 ++++++++++++++------------- api/sendfild/pb/sendfil.proto | 2 +- api/sendfild/service/service.go | 4 +- api/sendfild/service/service_test.go | 8 +- 5 files changed, 146 insertions(+), 145 deletions(-) diff --git a/api/sendfild/client/client.go b/api/sendfild/client/client.go index ec7c2ba12..0e0c15494 100644 --- a/api/sendfild/client/client.go +++ b/api/sendfild/client/client.go @@ -89,9 +89,9 @@ func ListTxnsTo(to string) ListTxnsOption { } } -func ListTxnsInvolving(involving string) ListTxnsOption { +func ListTxnsInvolvingAddress(involving string) ListTxnsOption { return func(req *pb.ListTxnsRequest) { - req.InvolvingFilter = involving + req.InvolvingAddressFilter = involving } } diff --git a/api/sendfild/pb/sendfil.pb.go b/api/sendfild/pb/sendfil.pb.go index ff7bf3f1f..01b4b01cd 100644 --- a/api/sendfild/pb/sendfil.pb.go +++ b/api/sendfild/pb/sendfil.pb.go @@ -477,7 +477,7 @@ type ListTxnsRequest struct { FromFilter string `protobuf:"bytes,1,opt,name=from_filter,json=fromFilter,proto3" json:"from_filter,omitempty"` ToFilter string `protobuf:"bytes,2,opt,name=to_filter,json=toFilter,proto3" json:"to_filter,omitempty"` - InvolvingFilter string `protobuf:"bytes,3,opt,name=involving_filter,json=involvingFilter,proto3" json:"involving_filter,omitempty"` + InvolvingAddressFilter string `protobuf:"bytes,3,opt,name=involving_address_filter,json=involvingAddressFilter,proto3" json:"involving_address_filter,omitempty"` AmountNanoFilLtFilter int64 `protobuf:"varint,4,opt,name=amount_nano_fil_lt_filter,json=amountNanoFilLtFilter,proto3" json:"amount_nano_fil_lt_filter,omitempty"` AmountNanoFilGtFilter int64 `protobuf:"varint,5,opt,name=amount_nano_fil_gt_filter,json=amountNanoFilGtFilter,proto3" json:"amount_nano_fil_gt_filter,omitempty"` AmountNanoFilLteqFilter int64 `protobuf:"varint,6,opt,name=amount_nano_fil_lteq_filter,json=amountNanoFilLteqFilter,proto3" json:"amount_nano_fil_lteq_filter,omitempty"` @@ -540,9 +540,9 @@ func (x *ListTxnsRequest) GetToFilter() string { return "" } -func (x *ListTxnsRequest) GetInvolvingFilter() string { +func (x *ListTxnsRequest) GetInvolvingAddressFilter() string { if x != nil { - return x.InvolvingFilter + return x.InvolvingAddressFilter } return "" } @@ -940,147 +940,148 @@ var file_api_sendfild_pb_sendfil_proto_rawDesc = []byte{ 0x0a, 0x0e, 0x47, 0x65, 0x74, 0x54, 0x78, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x26, 0x0a, 0x03, 0x74, 0x78, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x73, 0x65, 0x6e, 0x64, 0x66, 0x69, 0x6c, 0x64, 0x2e, 0x70, 0x62, 0x2e, - 0x54, 0x78, 0x6e, 0x52, 0x03, 0x74, 0x78, 0x6e, 0x22, 0x97, 0x07, 0x0a, 0x0f, 0x4c, 0x69, 0x73, + 0x54, 0x78, 0x6e, 0x52, 0x03, 0x74, 0x78, 0x6e, 0x22, 0xa6, 0x07, 0x0a, 0x0f, 0x4c, 0x69, 0x73, 0x74, 0x54, 0x78, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1f, 0x0a, 0x0b, 0x66, 0x72, 0x6f, 0x6d, 0x5f, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x66, 0x72, 0x6f, 0x6d, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x12, 0x1b, 0x0a, 0x09, 0x74, 0x6f, 0x5f, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x08, 0x74, 0x6f, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x12, 0x29, 0x0a, 0x10, 0x69, 0x6e, - 0x76, 0x6f, 0x6c, 0x76, 0x69, 0x6e, 0x67, 0x5f, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x18, 0x03, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x69, 0x6e, 0x76, 0x6f, 0x6c, 0x76, 0x69, 0x6e, 0x67, 0x46, - 0x69, 0x6c, 0x74, 0x65, 0x72, 0x12, 0x38, 0x0a, 0x19, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x5f, - 0x6e, 0x61, 0x6e, 0x6f, 0x5f, 0x66, 0x69, 0x6c, 0x5f, 0x6c, 0x74, 0x5f, 0x66, 0x69, 0x6c, 0x74, - 0x65, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x15, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, - 0x4e, 0x61, 0x6e, 0x6f, 0x46, 0x69, 0x6c, 0x4c, 0x74, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x12, - 0x38, 0x0a, 0x19, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x6e, 0x61, 0x6e, 0x6f, 0x5f, 0x66, - 0x69, 0x6c, 0x5f, 0x67, 0x74, 0x5f, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x18, 0x05, 0x20, 0x01, - 0x28, 0x03, 0x52, 0x15, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x4e, 0x61, 0x6e, 0x6f, 0x46, 0x69, - 0x6c, 0x47, 0x74, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x12, 0x3c, 0x0a, 0x1b, 0x61, 0x6d, 0x6f, - 0x75, 0x6e, 0x74, 0x5f, 0x6e, 0x61, 0x6e, 0x6f, 0x5f, 0x66, 0x69, 0x6c, 0x5f, 0x6c, 0x74, 0x65, - 0x71, 0x5f, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x18, 0x06, 0x20, 0x01, 0x28, 0x03, 0x52, 0x17, - 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x4e, 0x61, 0x6e, 0x6f, 0x46, 0x69, 0x6c, 0x4c, 0x74, 0x65, - 0x71, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x12, 0x3c, 0x0a, 0x1b, 0x61, 0x6d, 0x6f, 0x75, 0x6e, - 0x74, 0x5f, 0x6e, 0x61, 0x6e, 0x6f, 0x5f, 0x66, 0x69, 0x6c, 0x5f, 0x67, 0x74, 0x65, 0x71, 0x5f, - 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x18, 0x07, 0x20, 0x01, 0x28, 0x03, 0x52, 0x17, 0x61, 0x6d, - 0x6f, 0x75, 0x6e, 0x74, 0x4e, 0x61, 0x6e, 0x6f, 0x46, 0x69, 0x6c, 0x47, 0x74, 0x65, 0x71, 0x46, - 0x69, 0x6c, 0x74, 0x65, 0x72, 0x12, 0x38, 0x0a, 0x19, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x5f, - 0x6e, 0x61, 0x6e, 0x6f, 0x5f, 0x66, 0x69, 0x6c, 0x5f, 0x65, 0x71, 0x5f, 0x66, 0x69, 0x6c, 0x74, - 0x65, 0x72, 0x18, 0x08, 0x20, 0x01, 0x28, 0x03, 0x52, 0x15, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, - 0x4e, 0x61, 0x6e, 0x6f, 0x46, 0x69, 0x6c, 0x45, 0x71, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x12, - 0x4f, 0x0a, 0x14, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x65, - 0x5f, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1d, 0x2e, - 0x61, 0x70, 0x69, 0x2e, 0x73, 0x65, 0x6e, 0x64, 0x66, 0x69, 0x6c, 0x64, 0x2e, 0x70, 0x62, 0x2e, - 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x12, 0x6d, 0x65, - 0x73, 0x73, 0x61, 0x67, 0x65, 0x53, 0x74, 0x61, 0x74, 0x65, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, - 0x12, 0x45, 0x0a, 0x0e, 0x77, 0x61, 0x69, 0x74, 0x69, 0x6e, 0x67, 0x5f, 0x66, 0x69, 0x6c, 0x74, - 0x65, 0x72, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1e, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x73, - 0x65, 0x6e, 0x64, 0x66, 0x69, 0x6c, 0x64, 0x2e, 0x70, 0x62, 0x2e, 0x57, 0x61, 0x69, 0x74, 0x69, - 0x6e, 0x67, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x52, 0x0d, 0x77, 0x61, 0x69, 0x74, 0x69, 0x6e, - 0x67, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x12, 0x41, 0x0a, 0x0e, 0x63, 0x72, 0x65, 0x61, 0x74, - 0x65, 0x64, 0x5f, 0x62, 0x65, 0x66, 0x6f, 0x72, 0x65, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, - 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x0d, 0x63, 0x72, 0x65, - 0x61, 0x74, 0x65, 0x64, 0x42, 0x65, 0x66, 0x6f, 0x72, 0x65, 0x12, 0x3f, 0x0a, 0x0d, 0x63, 0x72, - 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x66, 0x74, 0x65, 0x72, 0x18, 0x0c, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x0c, 0x63, - 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x41, 0x66, 0x74, 0x65, 0x72, 0x12, 0x41, 0x0a, 0x0e, 0x75, - 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x62, 0x65, 0x66, 0x6f, 0x72, 0x65, 0x18, 0x0d, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, - 0x0d, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x42, 0x65, 0x66, 0x6f, 0x72, 0x65, 0x12, 0x3f, - 0x0a, 0x0d, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x66, 0x74, 0x65, 0x72, 0x18, - 0x0e, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, - 0x70, 0x52, 0x0c, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x41, 0x66, 0x74, 0x65, 0x72, 0x12, - 0x1c, 0x0a, 0x09, 0x61, 0x73, 0x63, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x18, 0x0f, 0x20, 0x01, - 0x28, 0x08, 0x52, 0x09, 0x61, 0x73, 0x63, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x12, 0x1d, 0x0a, - 0x0a, 0x6d, 0x6f, 0x72, 0x65, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x10, 0x20, 0x01, 0x28, - 0x03, 0x52, 0x09, 0x6d, 0x6f, 0x72, 0x65, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x14, 0x0a, 0x05, - 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x18, 0x11, 0x20, 0x01, 0x28, 0x03, 0x52, 0x05, 0x6c, 0x69, 0x6d, - 0x69, 0x74, 0x22, 0x6f, 0x0a, 0x10, 0x4c, 0x69, 0x73, 0x74, 0x54, 0x78, 0x6e, 0x73, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x28, 0x0a, 0x04, 0x74, 0x78, 0x6e, 0x73, 0x18, 0x01, - 0x20, 0x03, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x73, 0x65, 0x6e, 0x64, 0x66, - 0x69, 0x6c, 0x64, 0x2e, 0x70, 0x62, 0x2e, 0x54, 0x78, 0x6e, 0x52, 0x04, 0x74, 0x78, 0x6e, 0x73, - 0x12, 0x12, 0x0a, 0x04, 0x6d, 0x6f, 0x72, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x04, - 0x6d, 0x6f, 0x72, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x6d, 0x6f, 0x72, 0x65, 0x5f, 0x74, 0x6f, 0x6b, - 0x65, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x6d, 0x6f, 0x72, 0x65, 0x54, 0x6f, - 0x6b, 0x65, 0x6e, 0x22, 0x76, 0x0a, 0x0e, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x30, 0x0a, 0x05, 0x61, 0x66, 0x74, 0x65, 0x72, 0x18, 0x01, + 0x52, 0x08, 0x74, 0x6f, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x12, 0x38, 0x0a, 0x18, 0x69, 0x6e, + 0x76, 0x6f, 0x6c, 0x76, 0x69, 0x6e, 0x67, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x5f, + 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x16, 0x69, 0x6e, + 0x76, 0x6f, 0x6c, 0x76, 0x69, 0x6e, 0x67, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x46, 0x69, + 0x6c, 0x74, 0x65, 0x72, 0x12, 0x38, 0x0a, 0x19, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x6e, + 0x61, 0x6e, 0x6f, 0x5f, 0x66, 0x69, 0x6c, 0x5f, 0x6c, 0x74, 0x5f, 0x66, 0x69, 0x6c, 0x74, 0x65, + 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x15, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x4e, + 0x61, 0x6e, 0x6f, 0x46, 0x69, 0x6c, 0x4c, 0x74, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x12, 0x38, + 0x0a, 0x19, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x6e, 0x61, 0x6e, 0x6f, 0x5f, 0x66, 0x69, + 0x6c, 0x5f, 0x67, 0x74, 0x5f, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x18, 0x05, 0x20, 0x01, 0x28, + 0x03, 0x52, 0x15, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x4e, 0x61, 0x6e, 0x6f, 0x46, 0x69, 0x6c, + 0x47, 0x74, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x12, 0x3c, 0x0a, 0x1b, 0x61, 0x6d, 0x6f, 0x75, + 0x6e, 0x74, 0x5f, 0x6e, 0x61, 0x6e, 0x6f, 0x5f, 0x66, 0x69, 0x6c, 0x5f, 0x6c, 0x74, 0x65, 0x71, + 0x5f, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x18, 0x06, 0x20, 0x01, 0x28, 0x03, 0x52, 0x17, 0x61, + 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x4e, 0x61, 0x6e, 0x6f, 0x46, 0x69, 0x6c, 0x4c, 0x74, 0x65, 0x71, + 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x12, 0x3c, 0x0a, 0x1b, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, + 0x5f, 0x6e, 0x61, 0x6e, 0x6f, 0x5f, 0x66, 0x69, 0x6c, 0x5f, 0x67, 0x74, 0x65, 0x71, 0x5f, 0x66, + 0x69, 0x6c, 0x74, 0x65, 0x72, 0x18, 0x07, 0x20, 0x01, 0x28, 0x03, 0x52, 0x17, 0x61, 0x6d, 0x6f, + 0x75, 0x6e, 0x74, 0x4e, 0x61, 0x6e, 0x6f, 0x46, 0x69, 0x6c, 0x47, 0x74, 0x65, 0x71, 0x46, 0x69, + 0x6c, 0x74, 0x65, 0x72, 0x12, 0x38, 0x0a, 0x19, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x6e, + 0x61, 0x6e, 0x6f, 0x5f, 0x66, 0x69, 0x6c, 0x5f, 0x65, 0x71, 0x5f, 0x66, 0x69, 0x6c, 0x74, 0x65, + 0x72, 0x18, 0x08, 0x20, 0x01, 0x28, 0x03, 0x52, 0x15, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x4e, + 0x61, 0x6e, 0x6f, 0x46, 0x69, 0x6c, 0x45, 0x71, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x12, 0x4f, + 0x0a, 0x14, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x5f, + 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1d, 0x2e, 0x61, + 0x70, 0x69, 0x2e, 0x73, 0x65, 0x6e, 0x64, 0x66, 0x69, 0x6c, 0x64, 0x2e, 0x70, 0x62, 0x2e, 0x4d, + 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x12, 0x6d, 0x65, 0x73, + 0x73, 0x61, 0x67, 0x65, 0x53, 0x74, 0x61, 0x74, 0x65, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x12, + 0x45, 0x0a, 0x0e, 0x77, 0x61, 0x69, 0x74, 0x69, 0x6e, 0x67, 0x5f, 0x66, 0x69, 0x6c, 0x74, 0x65, + 0x72, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1e, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x73, 0x65, + 0x6e, 0x64, 0x66, 0x69, 0x6c, 0x64, 0x2e, 0x70, 0x62, 0x2e, 0x57, 0x61, 0x69, 0x74, 0x69, 0x6e, + 0x67, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x52, 0x0d, 0x77, 0x61, 0x69, 0x74, 0x69, 0x6e, 0x67, + 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x12, 0x41, 0x0a, 0x0e, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, + 0x64, 0x5f, 0x62, 0x65, 0x66, 0x6f, 0x72, 0x65, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, + 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, + 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x0d, 0x63, 0x72, 0x65, 0x61, + 0x74, 0x65, 0x64, 0x42, 0x65, 0x66, 0x6f, 0x72, 0x65, 0x12, 0x3f, 0x0a, 0x0d, 0x63, 0x72, 0x65, + 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x66, 0x74, 0x65, 0x72, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, + 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x0c, 0x63, 0x72, + 0x65, 0x61, 0x74, 0x65, 0x64, 0x41, 0x66, 0x74, 0x65, 0x72, 0x12, 0x41, 0x0a, 0x0e, 0x75, 0x70, + 0x64, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x62, 0x65, 0x66, 0x6f, 0x72, 0x65, 0x18, 0x0d, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x0d, + 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x42, 0x65, 0x66, 0x6f, 0x72, 0x65, 0x12, 0x3f, 0x0a, + 0x0d, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x66, 0x74, 0x65, 0x72, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, - 0x52, 0x05, 0x61, 0x66, 0x74, 0x65, 0x72, 0x12, 0x32, 0x0a, 0x06, 0x62, 0x65, 0x66, 0x6f, 0x72, - 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, - 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, - 0x61, 0x6d, 0x70, 0x52, 0x06, 0x62, 0x65, 0x66, 0x6f, 0x72, 0x65, 0x22, 0xc0, 0x03, 0x0a, 0x0f, - 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, - 0x1d, 0x0a, 0x0a, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x74, 0x78, 0x6e, 0x73, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x03, 0x52, 0x09, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x54, 0x78, 0x6e, 0x73, 0x12, 0x23, - 0x0a, 0x0d, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x70, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0c, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x50, 0x65, 0x6e, 0x64, - 0x69, 0x6e, 0x67, 0x12, 0x21, 0x0a, 0x0c, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x61, 0x63, 0x74, - 0x69, 0x76, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0b, 0x63, 0x6f, 0x75, 0x6e, 0x74, - 0x41, 0x63, 0x74, 0x69, 0x76, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x5f, - 0x66, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0b, 0x63, 0x6f, - 0x75, 0x6e, 0x74, 0x46, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x12, 0x23, 0x0a, 0x0d, 0x63, 0x6f, 0x75, - 0x6e, 0x74, 0x5f, 0x77, 0x61, 0x69, 0x74, 0x69, 0x6e, 0x67, 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, - 0x52, 0x0c, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x57, 0x61, 0x69, 0x74, 0x69, 0x6e, 0x67, 0x12, 0x28, - 0x0a, 0x10, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x66, 0x72, 0x6f, 0x6d, 0x5f, 0x61, 0x64, 0x64, - 0x72, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0e, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x46, - 0x72, 0x6f, 0x6d, 0x41, 0x64, 0x64, 0x72, 0x73, 0x12, 0x24, 0x0a, 0x0e, 0x63, 0x6f, 0x75, 0x6e, - 0x74, 0x5f, 0x74, 0x6f, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x73, 0x18, 0x07, 0x20, 0x01, 0x28, 0x03, - 0x52, 0x0c, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x54, 0x6f, 0x41, 0x64, 0x64, 0x72, 0x73, 0x12, 0x2d, - 0x0a, 0x13, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x6e, 0x61, 0x6e, 0x6f, 0x5f, 0x66, 0x69, 0x6c, - 0x5f, 0x73, 0x65, 0x6e, 0x74, 0x18, 0x08, 0x20, 0x01, 0x28, 0x03, 0x52, 0x10, 0x74, 0x6f, 0x74, - 0x61, 0x6c, 0x4e, 0x61, 0x6e, 0x6f, 0x46, 0x69, 0x6c, 0x53, 0x65, 0x6e, 0x74, 0x12, 0x29, 0x0a, - 0x11, 0x61, 0x76, 0x67, 0x5f, 0x6e, 0x61, 0x6e, 0x6f, 0x5f, 0x66, 0x69, 0x6c, 0x5f, 0x73, 0x65, - 0x6e, 0x74, 0x18, 0x09, 0x20, 0x01, 0x28, 0x01, 0x52, 0x0e, 0x61, 0x76, 0x67, 0x4e, 0x61, 0x6e, - 0x6f, 0x46, 0x69, 0x6c, 0x53, 0x65, 0x6e, 0x74, 0x12, 0x29, 0x0a, 0x11, 0x6d, 0x61, 0x78, 0x5f, - 0x6e, 0x61, 0x6e, 0x6f, 0x5f, 0x66, 0x69, 0x6c, 0x5f, 0x73, 0x65, 0x6e, 0x74, 0x18, 0x0a, 0x20, - 0x01, 0x28, 0x03, 0x52, 0x0e, 0x6d, 0x61, 0x78, 0x4e, 0x61, 0x6e, 0x6f, 0x46, 0x69, 0x6c, 0x53, - 0x65, 0x6e, 0x74, 0x12, 0x29, 0x0a, 0x11, 0x6d, 0x69, 0x6e, 0x5f, 0x6e, 0x61, 0x6e, 0x6f, 0x5f, - 0x66, 0x69, 0x6c, 0x5f, 0x73, 0x65, 0x6e, 0x74, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0e, - 0x6d, 0x69, 0x6e, 0x4e, 0x61, 0x6e, 0x6f, 0x46, 0x69, 0x6c, 0x53, 0x65, 0x6e, 0x74, 0x2a, 0x7c, - 0x0a, 0x0c, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x1d, - 0x0a, 0x19, 0x4d, 0x45, 0x53, 0x53, 0x41, 0x47, 0x45, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x45, 0x5f, - 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x19, 0x0a, - 0x15, 0x4d, 0x45, 0x53, 0x53, 0x41, 0x47, 0x45, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x45, 0x5f, 0x50, - 0x45, 0x4e, 0x44, 0x49, 0x4e, 0x47, 0x10, 0x01, 0x12, 0x18, 0x0a, 0x14, 0x4d, 0x45, 0x53, 0x53, - 0x41, 0x47, 0x45, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x45, 0x5f, 0x41, 0x43, 0x54, 0x49, 0x56, 0x45, - 0x10, 0x02, 0x12, 0x18, 0x0a, 0x14, 0x4d, 0x45, 0x53, 0x53, 0x41, 0x47, 0x45, 0x5f, 0x53, 0x54, - 0x41, 0x54, 0x45, 0x5f, 0x46, 0x41, 0x49, 0x4c, 0x45, 0x44, 0x10, 0x03, 0x2a, 0x6b, 0x0a, 0x0d, - 0x57, 0x61, 0x69, 0x74, 0x69, 0x6e, 0x67, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x12, 0x1e, 0x0a, - 0x1a, 0x57, 0x41, 0x49, 0x54, 0x49, 0x4e, 0x47, 0x5f, 0x46, 0x49, 0x4c, 0x54, 0x45, 0x52, 0x5f, - 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x1a, 0x0a, - 0x16, 0x57, 0x41, 0x49, 0x54, 0x49, 0x4e, 0x47, 0x5f, 0x46, 0x49, 0x4c, 0x54, 0x45, 0x52, 0x5f, - 0x57, 0x41, 0x49, 0x54, 0x49, 0x4e, 0x47, 0x10, 0x01, 0x12, 0x1e, 0x0a, 0x1a, 0x57, 0x41, 0x49, - 0x54, 0x49, 0x4e, 0x47, 0x5f, 0x46, 0x49, 0x4c, 0x54, 0x45, 0x52, 0x5f, 0x4e, 0x4f, 0x54, 0x5f, - 0x57, 0x41, 0x49, 0x54, 0x49, 0x4e, 0x47, 0x10, 0x02, 0x32, 0xd0, 0x02, 0x0a, 0x0e, 0x53, 0x65, - 0x6e, 0x64, 0x46, 0x69, 0x6c, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x4e, 0x0a, 0x07, - 0x53, 0x65, 0x6e, 0x64, 0x46, 0x69, 0x6c, 0x12, 0x1f, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x73, 0x65, + 0x52, 0x0c, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x41, 0x66, 0x74, 0x65, 0x72, 0x12, 0x1c, + 0x0a, 0x09, 0x61, 0x73, 0x63, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x18, 0x0f, 0x20, 0x01, 0x28, + 0x08, 0x52, 0x09, 0x61, 0x73, 0x63, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x12, 0x1d, 0x0a, 0x0a, + 0x6d, 0x6f, 0x72, 0x65, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x10, 0x20, 0x01, 0x28, 0x03, + 0x52, 0x09, 0x6d, 0x6f, 0x72, 0x65, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x14, 0x0a, 0x05, 0x6c, + 0x69, 0x6d, 0x69, 0x74, 0x18, 0x11, 0x20, 0x01, 0x28, 0x03, 0x52, 0x05, 0x6c, 0x69, 0x6d, 0x69, + 0x74, 0x22, 0x6f, 0x0a, 0x10, 0x4c, 0x69, 0x73, 0x74, 0x54, 0x78, 0x6e, 0x73, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x28, 0x0a, 0x04, 0x74, 0x78, 0x6e, 0x73, 0x18, 0x01, 0x20, + 0x03, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x73, 0x65, 0x6e, 0x64, 0x66, 0x69, + 0x6c, 0x64, 0x2e, 0x70, 0x62, 0x2e, 0x54, 0x78, 0x6e, 0x52, 0x04, 0x74, 0x78, 0x6e, 0x73, 0x12, + 0x12, 0x0a, 0x04, 0x6d, 0x6f, 0x72, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x04, 0x6d, + 0x6f, 0x72, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x6d, 0x6f, 0x72, 0x65, 0x5f, 0x74, 0x6f, 0x6b, 0x65, + 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x6d, 0x6f, 0x72, 0x65, 0x54, 0x6f, 0x6b, + 0x65, 0x6e, 0x22, 0x76, 0x0a, 0x0e, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x12, 0x30, 0x0a, 0x05, 0x61, 0x66, 0x74, 0x65, 0x72, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, + 0x05, 0x61, 0x66, 0x74, 0x65, 0x72, 0x12, 0x32, 0x0a, 0x06, 0x62, 0x65, 0x66, 0x6f, 0x72, 0x65, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, + 0x6d, 0x70, 0x52, 0x06, 0x62, 0x65, 0x66, 0x6f, 0x72, 0x65, 0x22, 0xc0, 0x03, 0x0a, 0x0f, 0x53, + 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1d, + 0x0a, 0x0a, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x74, 0x78, 0x6e, 0x73, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x03, 0x52, 0x09, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x54, 0x78, 0x6e, 0x73, 0x12, 0x23, 0x0a, + 0x0d, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x70, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x03, 0x52, 0x0c, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x50, 0x65, 0x6e, 0x64, 0x69, + 0x6e, 0x67, 0x12, 0x21, 0x0a, 0x0c, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x61, 0x63, 0x74, 0x69, + 0x76, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0b, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x41, + 0x63, 0x74, 0x69, 0x76, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x66, + 0x61, 0x69, 0x6c, 0x65, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0b, 0x63, 0x6f, 0x75, + 0x6e, 0x74, 0x46, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x12, 0x23, 0x0a, 0x0d, 0x63, 0x6f, 0x75, 0x6e, + 0x74, 0x5f, 0x77, 0x61, 0x69, 0x74, 0x69, 0x6e, 0x67, 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, 0x52, + 0x0c, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x57, 0x61, 0x69, 0x74, 0x69, 0x6e, 0x67, 0x12, 0x28, 0x0a, + 0x10, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x66, 0x72, 0x6f, 0x6d, 0x5f, 0x61, 0x64, 0x64, 0x72, + 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0e, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x46, 0x72, + 0x6f, 0x6d, 0x41, 0x64, 0x64, 0x72, 0x73, 0x12, 0x24, 0x0a, 0x0e, 0x63, 0x6f, 0x75, 0x6e, 0x74, + 0x5f, 0x74, 0x6f, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x73, 0x18, 0x07, 0x20, 0x01, 0x28, 0x03, 0x52, + 0x0c, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x54, 0x6f, 0x41, 0x64, 0x64, 0x72, 0x73, 0x12, 0x2d, 0x0a, + 0x13, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x6e, 0x61, 0x6e, 0x6f, 0x5f, 0x66, 0x69, 0x6c, 0x5f, + 0x73, 0x65, 0x6e, 0x74, 0x18, 0x08, 0x20, 0x01, 0x28, 0x03, 0x52, 0x10, 0x74, 0x6f, 0x74, 0x61, + 0x6c, 0x4e, 0x61, 0x6e, 0x6f, 0x46, 0x69, 0x6c, 0x53, 0x65, 0x6e, 0x74, 0x12, 0x29, 0x0a, 0x11, + 0x61, 0x76, 0x67, 0x5f, 0x6e, 0x61, 0x6e, 0x6f, 0x5f, 0x66, 0x69, 0x6c, 0x5f, 0x73, 0x65, 0x6e, + 0x74, 0x18, 0x09, 0x20, 0x01, 0x28, 0x01, 0x52, 0x0e, 0x61, 0x76, 0x67, 0x4e, 0x61, 0x6e, 0x6f, + 0x46, 0x69, 0x6c, 0x53, 0x65, 0x6e, 0x74, 0x12, 0x29, 0x0a, 0x11, 0x6d, 0x61, 0x78, 0x5f, 0x6e, + 0x61, 0x6e, 0x6f, 0x5f, 0x66, 0x69, 0x6c, 0x5f, 0x73, 0x65, 0x6e, 0x74, 0x18, 0x0a, 0x20, 0x01, + 0x28, 0x03, 0x52, 0x0e, 0x6d, 0x61, 0x78, 0x4e, 0x61, 0x6e, 0x6f, 0x46, 0x69, 0x6c, 0x53, 0x65, + 0x6e, 0x74, 0x12, 0x29, 0x0a, 0x11, 0x6d, 0x69, 0x6e, 0x5f, 0x6e, 0x61, 0x6e, 0x6f, 0x5f, 0x66, + 0x69, 0x6c, 0x5f, 0x73, 0x65, 0x6e, 0x74, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0e, 0x6d, + 0x69, 0x6e, 0x4e, 0x61, 0x6e, 0x6f, 0x46, 0x69, 0x6c, 0x53, 0x65, 0x6e, 0x74, 0x2a, 0x7c, 0x0a, + 0x0c, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x1d, 0x0a, + 0x19, 0x4d, 0x45, 0x53, 0x53, 0x41, 0x47, 0x45, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x45, 0x5f, 0x55, + 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x19, 0x0a, 0x15, + 0x4d, 0x45, 0x53, 0x53, 0x41, 0x47, 0x45, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x45, 0x5f, 0x50, 0x45, + 0x4e, 0x44, 0x49, 0x4e, 0x47, 0x10, 0x01, 0x12, 0x18, 0x0a, 0x14, 0x4d, 0x45, 0x53, 0x53, 0x41, + 0x47, 0x45, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x45, 0x5f, 0x41, 0x43, 0x54, 0x49, 0x56, 0x45, 0x10, + 0x02, 0x12, 0x18, 0x0a, 0x14, 0x4d, 0x45, 0x53, 0x53, 0x41, 0x47, 0x45, 0x5f, 0x53, 0x54, 0x41, + 0x54, 0x45, 0x5f, 0x46, 0x41, 0x49, 0x4c, 0x45, 0x44, 0x10, 0x03, 0x2a, 0x6b, 0x0a, 0x0d, 0x57, + 0x61, 0x69, 0x74, 0x69, 0x6e, 0x67, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x12, 0x1e, 0x0a, 0x1a, + 0x57, 0x41, 0x49, 0x54, 0x49, 0x4e, 0x47, 0x5f, 0x46, 0x49, 0x4c, 0x54, 0x45, 0x52, 0x5f, 0x55, + 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x1a, 0x0a, 0x16, + 0x57, 0x41, 0x49, 0x54, 0x49, 0x4e, 0x47, 0x5f, 0x46, 0x49, 0x4c, 0x54, 0x45, 0x52, 0x5f, 0x57, + 0x41, 0x49, 0x54, 0x49, 0x4e, 0x47, 0x10, 0x01, 0x12, 0x1e, 0x0a, 0x1a, 0x57, 0x41, 0x49, 0x54, + 0x49, 0x4e, 0x47, 0x5f, 0x46, 0x49, 0x4c, 0x54, 0x45, 0x52, 0x5f, 0x4e, 0x4f, 0x54, 0x5f, 0x57, + 0x41, 0x49, 0x54, 0x49, 0x4e, 0x47, 0x10, 0x02, 0x32, 0xd0, 0x02, 0x0a, 0x0e, 0x53, 0x65, 0x6e, + 0x64, 0x46, 0x69, 0x6c, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x4e, 0x0a, 0x07, 0x53, + 0x65, 0x6e, 0x64, 0x46, 0x69, 0x6c, 0x12, 0x1f, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x73, 0x65, 0x6e, + 0x64, 0x66, 0x69, 0x6c, 0x64, 0x2e, 0x70, 0x62, 0x2e, 0x53, 0x65, 0x6e, 0x64, 0x46, 0x69, 0x6c, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x20, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x73, 0x65, 0x6e, 0x64, 0x66, 0x69, 0x6c, 0x64, 0x2e, 0x70, 0x62, 0x2e, 0x53, 0x65, 0x6e, 0x64, 0x46, 0x69, - 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x20, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x73, - 0x65, 0x6e, 0x64, 0x66, 0x69, 0x6c, 0x64, 0x2e, 0x70, 0x62, 0x2e, 0x53, 0x65, 0x6e, 0x64, 0x46, - 0x69, 0x6c, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x4b, 0x0a, 0x06, - 0x47, 0x65, 0x74, 0x54, 0x78, 0x6e, 0x12, 0x1e, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x73, 0x65, 0x6e, - 0x64, 0x66, 0x69, 0x6c, 0x64, 0x2e, 0x70, 0x62, 0x2e, 0x47, 0x65, 0x74, 0x54, 0x78, 0x6e, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x73, 0x65, 0x6e, - 0x64, 0x66, 0x69, 0x6c, 0x64, 0x2e, 0x70, 0x62, 0x2e, 0x47, 0x65, 0x74, 0x54, 0x78, 0x6e, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x51, 0x0a, 0x08, 0x4c, 0x69, 0x73, - 0x74, 0x54, 0x78, 0x6e, 0x73, 0x12, 0x20, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x73, 0x65, 0x6e, 0x64, - 0x66, 0x69, 0x6c, 0x64, 0x2e, 0x70, 0x62, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x54, 0x78, 0x6e, 0x73, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x21, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x73, 0x65, - 0x6e, 0x64, 0x66, 0x69, 0x6c, 0x64, 0x2e, 0x70, 0x62, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x54, 0x78, - 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x4e, 0x0a, 0x07, - 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x12, 0x1f, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x73, 0x65, + 0x6c, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x4b, 0x0a, 0x06, 0x47, + 0x65, 0x74, 0x54, 0x78, 0x6e, 0x12, 0x1e, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x73, 0x65, 0x6e, 0x64, + 0x66, 0x69, 0x6c, 0x64, 0x2e, 0x70, 0x62, 0x2e, 0x47, 0x65, 0x74, 0x54, 0x78, 0x6e, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x73, 0x65, 0x6e, 0x64, + 0x66, 0x69, 0x6c, 0x64, 0x2e, 0x70, 0x62, 0x2e, 0x47, 0x65, 0x74, 0x54, 0x78, 0x6e, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x51, 0x0a, 0x08, 0x4c, 0x69, 0x73, 0x74, + 0x54, 0x78, 0x6e, 0x73, 0x12, 0x20, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x73, 0x65, 0x6e, 0x64, 0x66, + 0x69, 0x6c, 0x64, 0x2e, 0x70, 0x62, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x54, 0x78, 0x6e, 0x73, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x21, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x73, 0x65, 0x6e, + 0x64, 0x66, 0x69, 0x6c, 0x64, 0x2e, 0x70, 0x62, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x54, 0x78, 0x6e, + 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x4e, 0x0a, 0x07, 0x53, + 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x12, 0x1f, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x73, 0x65, 0x6e, + 0x64, 0x66, 0x69, 0x6c, 0x64, 0x2e, 0x70, 0x62, 0x2e, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x20, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x73, 0x65, 0x6e, 0x64, 0x66, 0x69, 0x6c, 0x64, 0x2e, 0x70, 0x62, 0x2e, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, - 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x20, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x73, - 0x65, 0x6e, 0x64, 0x66, 0x69, 0x6c, 0x64, 0x2e, 0x70, 0x62, 0x2e, 0x53, 0x75, 0x6d, 0x6d, 0x61, - 0x72, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x42, 0x31, 0x5a, 0x2f, - 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x74, 0x65, 0x78, 0x74, 0x69, - 0x6c, 0x65, 0x69, 0x6f, 0x2f, 0x74, 0x65, 0x78, 0x74, 0x69, 0x6c, 0x65, 0x2f, 0x76, 0x32, 0x2f, - 0x61, 0x70, 0x69, 0x2f, 0x73, 0x65, 0x6e, 0x64, 0x66, 0x69, 0x6c, 0x64, 0x2f, 0x70, 0x62, 0x62, - 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x42, 0x31, 0x5a, 0x2f, 0x67, + 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x74, 0x65, 0x78, 0x74, 0x69, 0x6c, + 0x65, 0x69, 0x6f, 0x2f, 0x74, 0x65, 0x78, 0x74, 0x69, 0x6c, 0x65, 0x2f, 0x76, 0x32, 0x2f, 0x61, + 0x70, 0x69, 0x2f, 0x73, 0x65, 0x6e, 0x64, 0x66, 0x69, 0x6c, 0x64, 0x2f, 0x70, 0x62, 0x62, 0x06, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/api/sendfild/pb/sendfil.proto b/api/sendfild/pb/sendfil.proto index 913d90292..6e432be10 100644 --- a/api/sendfild/pb/sendfil.proto +++ b/api/sendfild/pb/sendfil.proto @@ -53,7 +53,7 @@ message GetTxnResponse { message ListTxnsRequest { string from_filter = 1; string to_filter = 2; - string involving_filter = 3; + string involving_address_filter = 3; int64 amount_nano_fil_lt_filter = 4; int64 amount_nano_fil_gt_filter = 5; int64 amount_nano_fil_lteq_filter = 6; diff --git a/api/sendfild/service/service.go b/api/sendfild/service/service.go index 2bbf79611..2468b99ee 100644 --- a/api/sendfild/service/service.go +++ b/api/sendfild/service/service.go @@ -308,8 +308,8 @@ func (s *Service) ListTxns(ctx context.Context, req *pb.ListTxnsRequest) (*pb.Li filter := bson.M{} // Involving/from/to - if req.InvolvingFilter != "" { - filter["$or"] = bson.A{bson.M{"from": req.InvolvingFilter}, bson.M{"to": req.InvolvingFilter}} + if req.InvolvingAddressFilter != "" { + filter["$or"] = bson.A{bson.M{"from": req.InvolvingAddressFilter}, bson.M{"to": req.InvolvingAddressFilter}} } else { if req.FromFilter != "" { filter["from"] = req.FromFilter diff --git a/api/sendfild/service/service_test.go b/api/sendfild/service/service_test.go index b68fc6136..76b8bc99c 100644 --- a/api/sendfild/service/service_test.go +++ b/api/sendfild/service/service_test.go @@ -167,7 +167,7 @@ func TestListTxnsTo(t *testing.T) { require.Len(t, res.Txns, 1) } -func TestListTxnsInvolving(t *testing.T) { +func TestListTxnsInvolvingAddress(t *testing.T) { c, lc, dAddr, cleanup := requireSetup(t, ctx) defer cleanup() addr1 := requireLotusAddress(t, ctx, lc) @@ -176,13 +176,13 @@ func TestListTxnsInvolving(t *testing.T) { requireSendFil(t, ctx, c, dAddr.String(), addr1.String(), oneFil, false) requireSendFil(t, ctx, c, dAddr.String(), addr2.String(), oneFil*2, true) requireSendFil(t, ctx, c, addr2.String(), addr1.String(), oneFil, false) - res, err := c.ListTxns(ctx, &pb.ListTxnsRequest{InvolvingFilter: dAddr.String()}) + res, err := c.ListTxns(ctx, &pb.ListTxnsRequest{InvolvingAddressFilter: dAddr.String()}) require.NoError(t, err) require.Len(t, res.Txns, 3) - res, err = c.ListTxns(ctx, &pb.ListTxnsRequest{InvolvingFilter: addr1.String()}) + res, err = c.ListTxns(ctx, &pb.ListTxnsRequest{InvolvingAddressFilter: addr1.String()}) require.NoError(t, err) require.Len(t, res.Txns, 3) - res, err = c.ListTxns(ctx, &pb.ListTxnsRequest{InvolvingFilter: addr2.String()}) + res, err = c.ListTxns(ctx, &pb.ListTxnsRequest{InvolvingAddressFilter: addr2.String()}) require.NoError(t, err) require.Len(t, res.Txns, 2) }