diff --git a/channeldb/payments.go b/channeldb/payments.go index 9eabe37d..934a3946 100644 --- a/channeldb/payments.go +++ b/channeldb/payments.go @@ -97,6 +97,18 @@ const ( // TODO(halseth): cancel state. ) +// String returns a human readable FailureReason +func (r FailureReason) String() string { + switch r { + case FailureReasonTimeout: + return "timeout" + case FailureReasonNoRoute: + return "no_route" + } + + return "unknown" +} + // PaymentStatus represent current status of payment type PaymentStatus byte diff --git a/lnrpc/routerrpc/config_active.go b/lnrpc/routerrpc/config_active.go index d04f5821..36877c36 100644 --- a/lnrpc/routerrpc/config_active.go +++ b/lnrpc/routerrpc/config_active.go @@ -5,7 +5,6 @@ package routerrpc import ( "time" - "github.com/btcsuite/btcd/chaincfg" "github.com/btcsuite/btcutil" "github.com/lightningnetwork/lnd/lnwire" "github.com/lightningnetwork/lnd/macaroons" diff --git a/lnrpc/routerrpc/router.pb.go b/lnrpc/routerrpc/router.pb.go index 224bd4d0..c38c5e9c 100644 --- a/lnrpc/routerrpc/router.pb.go +++ b/lnrpc/routerrpc/router.pb.go @@ -23,6 +23,46 @@ var _ = math.Inf // proto package needs to be updated. const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package +type PaymentState int32 + +const ( + //* + //Payment is still in flight. + PaymentState_IN_FLIGHT PaymentState = 0 + //* + //Payment completed successfully. + PaymentState_SUCCEEDED PaymentState = 1 + //* + //There are more routes to try, but the payment timeout was exceeded. + PaymentState_FAILED_TIMEOUT PaymentState = 2 + //* + //All possible routes were tried and failed permanently. Or were no + //routes to the destination at all. + PaymentState_FAILED_NO_ROUTE PaymentState = 3 +) + +var PaymentState_name = map[int32]string{ + 0: "IN_FLIGHT", + 1: "SUCCEEDED", + 2: "FAILED_TIMEOUT", + 3: "FAILED_NO_ROUTE", +} + +var PaymentState_value = map[string]int32{ + "IN_FLIGHT": 0, + "SUCCEEDED": 1, + "FAILED_TIMEOUT": 2, + "FAILED_NO_ROUTE": 3, +} + +func (x PaymentState) String() string { + return proto.EnumName(PaymentState_name, int32(x)) +} + +func (PaymentState) EnumDescriptor() ([]byte, []int) { + return fileDescriptor_7a0613f69d37b0a5, []int{0} +} + type Failure_FailureCode int32 const ( @@ -109,10 +149,10 @@ func (x Failure_FailureCode) String() string { } func (Failure_FailureCode) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_7a0613f69d37b0a5, []int{6, 0} + return fileDescriptor_7a0613f69d37b0a5, []int{7, 0} } -type PaymentRequest struct { +type SendPaymentRequest struct { /// The identity pubkey of the payment recipient Dest []byte `protobuf:"bytes,1,opt,name=dest,proto3" json:"dest,omitempty"` /// Number of satoshis to send. @@ -155,154 +195,192 @@ type PaymentRequest struct { XXX_sizecache int32 `json:"-"` } -func (m *PaymentRequest) Reset() { *m = PaymentRequest{} } -func (m *PaymentRequest) String() string { return proto.CompactTextString(m) } -func (*PaymentRequest) ProtoMessage() {} -func (*PaymentRequest) Descriptor() ([]byte, []int) { +func (m *SendPaymentRequest) Reset() { *m = SendPaymentRequest{} } +func (m *SendPaymentRequest) String() string { return proto.CompactTextString(m) } +func (*SendPaymentRequest) ProtoMessage() {} +func (*SendPaymentRequest) Descriptor() ([]byte, []int) { return fileDescriptor_7a0613f69d37b0a5, []int{0} } -func (m *PaymentRequest) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_PaymentRequest.Unmarshal(m, b) +func (m *SendPaymentRequest) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_SendPaymentRequest.Unmarshal(m, b) } -func (m *PaymentRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_PaymentRequest.Marshal(b, m, deterministic) +func (m *SendPaymentRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_SendPaymentRequest.Marshal(b, m, deterministic) } -func (m *PaymentRequest) XXX_Merge(src proto.Message) { - xxx_messageInfo_PaymentRequest.Merge(m, src) +func (m *SendPaymentRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_SendPaymentRequest.Merge(m, src) } -func (m *PaymentRequest) XXX_Size() int { - return xxx_messageInfo_PaymentRequest.Size(m) +func (m *SendPaymentRequest) XXX_Size() int { + return xxx_messageInfo_SendPaymentRequest.Size(m) } -func (m *PaymentRequest) XXX_DiscardUnknown() { - xxx_messageInfo_PaymentRequest.DiscardUnknown(m) +func (m *SendPaymentRequest) XXX_DiscardUnknown() { + xxx_messageInfo_SendPaymentRequest.DiscardUnknown(m) } -var xxx_messageInfo_PaymentRequest proto.InternalMessageInfo +var xxx_messageInfo_SendPaymentRequest proto.InternalMessageInfo -func (m *PaymentRequest) GetDest() []byte { +func (m *SendPaymentRequest) GetDest() []byte { if m != nil { return m.Dest } return nil } -func (m *PaymentRequest) GetAmt() int64 { +func (m *SendPaymentRequest) GetAmt() int64 { if m != nil { return m.Amt } return 0 } -func (m *PaymentRequest) GetPaymentHash() []byte { +func (m *SendPaymentRequest) GetPaymentHash() []byte { if m != nil { return m.PaymentHash } return nil } -func (m *PaymentRequest) GetFinalCltvDelta() int32 { +func (m *SendPaymentRequest) GetFinalCltvDelta() int32 { if m != nil { return m.FinalCltvDelta } return 0 } -func (m *PaymentRequest) GetPaymentRequest() string { +func (m *SendPaymentRequest) GetPaymentRequest() string { if m != nil { return m.PaymentRequest } return "" } -func (m *PaymentRequest) GetTimeoutSeconds() int32 { +func (m *SendPaymentRequest) GetTimeoutSeconds() int32 { if m != nil { return m.TimeoutSeconds } return 0 } -func (m *PaymentRequest) GetFeeLimitSat() int64 { +func (m *SendPaymentRequest) GetFeeLimitSat() int64 { if m != nil { return m.FeeLimitSat } return 0 } -func (m *PaymentRequest) GetOutgoingChanId() uint64 { +func (m *SendPaymentRequest) GetOutgoingChanId() uint64 { if m != nil { return m.OutgoingChanId } return 0 } -func (m *PaymentRequest) GetCltvLimit() int32 { +func (m *SendPaymentRequest) GetCltvLimit() int32 { if m != nil { return m.CltvLimit } return 0 } -type PaymentResponse struct { - //* - //The payment hash that we paid to. Provided so callers are able to map - //responses (which may be streaming) back to their original requests. - PayHash []byte `protobuf:"bytes,1,opt,name=pay_hash,json=payHash,proto3" json:"pay_hash,omitempty"` - //* - //The pre-image of the payment successfully completed. - PreImage []byte `protobuf:"bytes,2,opt,name=pre_image,json=preImage,proto3" json:"pre_image,omitempty"` - //* - //If not an empty string, then a string representation of the payment error. - PaymentErr string `protobuf:"bytes,3,opt,name=payment_err,json=paymentErr,proto3" json:"payment_err,omitempty"` +type TrackPaymentRequest struct { + /// The hash of the payment to look up. + PaymentHash []byte `protobuf:"bytes,1,opt,name=payment_hash,json=paymentHash,proto3" json:"payment_hash,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` } -func (m *PaymentResponse) Reset() { *m = PaymentResponse{} } -func (m *PaymentResponse) String() string { return proto.CompactTextString(m) } -func (*PaymentResponse) ProtoMessage() {} -func (*PaymentResponse) Descriptor() ([]byte, []int) { +func (m *TrackPaymentRequest) Reset() { *m = TrackPaymentRequest{} } +func (m *TrackPaymentRequest) String() string { return proto.CompactTextString(m) } +func (*TrackPaymentRequest) ProtoMessage() {} +func (*TrackPaymentRequest) Descriptor() ([]byte, []int) { return fileDescriptor_7a0613f69d37b0a5, []int{1} } -func (m *PaymentResponse) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_PaymentResponse.Unmarshal(m, b) +func (m *TrackPaymentRequest) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_TrackPaymentRequest.Unmarshal(m, b) } -func (m *PaymentResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_PaymentResponse.Marshal(b, m, deterministic) +func (m *TrackPaymentRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_TrackPaymentRequest.Marshal(b, m, deterministic) } -func (m *PaymentResponse) XXX_Merge(src proto.Message) { - xxx_messageInfo_PaymentResponse.Merge(m, src) +func (m *TrackPaymentRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_TrackPaymentRequest.Merge(m, src) } -func (m *PaymentResponse) XXX_Size() int { - return xxx_messageInfo_PaymentResponse.Size(m) +func (m *TrackPaymentRequest) XXX_Size() int { + return xxx_messageInfo_TrackPaymentRequest.Size(m) } -func (m *PaymentResponse) XXX_DiscardUnknown() { - xxx_messageInfo_PaymentResponse.DiscardUnknown(m) +func (m *TrackPaymentRequest) XXX_DiscardUnknown() { + xxx_messageInfo_TrackPaymentRequest.DiscardUnknown(m) } -var xxx_messageInfo_PaymentResponse proto.InternalMessageInfo +var xxx_messageInfo_TrackPaymentRequest proto.InternalMessageInfo -func (m *PaymentResponse) GetPayHash() []byte { +func (m *TrackPaymentRequest) GetPaymentHash() []byte { if m != nil { - return m.PayHash + return m.PaymentHash } return nil } -func (m *PaymentResponse) GetPreImage() []byte { +type PaymentStatus struct { + /// Current state the payment is in. + State PaymentState `protobuf:"varint,1,opt,name=state,proto3,enum=routerrpc.PaymentState" json:"state,omitempty"` + //* + //The pre-image of the payment when state is SUCCEEDED. + Preimage []byte `protobuf:"bytes,2,opt,name=preimage,proto3" json:"preimage,omitempty"` + //* + //The taken route when state is SUCCEEDED. + Route *lnrpc.Route `protobuf:"bytes,3,opt,name=route,proto3" json:"route,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *PaymentStatus) Reset() { *m = PaymentStatus{} } +func (m *PaymentStatus) String() string { return proto.CompactTextString(m) } +func (*PaymentStatus) ProtoMessage() {} +func (*PaymentStatus) Descriptor() ([]byte, []int) { + return fileDescriptor_7a0613f69d37b0a5, []int{2} +} + +func (m *PaymentStatus) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_PaymentStatus.Unmarshal(m, b) +} +func (m *PaymentStatus) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_PaymentStatus.Marshal(b, m, deterministic) +} +func (m *PaymentStatus) XXX_Merge(src proto.Message) { + xxx_messageInfo_PaymentStatus.Merge(m, src) +} +func (m *PaymentStatus) XXX_Size() int { + return xxx_messageInfo_PaymentStatus.Size(m) +} +func (m *PaymentStatus) XXX_DiscardUnknown() { + xxx_messageInfo_PaymentStatus.DiscardUnknown(m) +} + +var xxx_messageInfo_PaymentStatus proto.InternalMessageInfo + +func (m *PaymentStatus) GetState() PaymentState { if m != nil { - return m.PreImage + return m.State + } + return PaymentState_IN_FLIGHT +} + +func (m *PaymentStatus) GetPreimage() []byte { + if m != nil { + return m.Preimage } return nil } -func (m *PaymentResponse) GetPaymentErr() string { +func (m *PaymentStatus) GetRoute() *lnrpc.Route { if m != nil { - return m.PaymentErr + return m.Route } - return "" + return nil } type RouteFeeRequest struct { @@ -321,7 +399,7 @@ func (m *RouteFeeRequest) Reset() { *m = RouteFeeRequest{} } func (m *RouteFeeRequest) String() string { return proto.CompactTextString(m) } func (*RouteFeeRequest) ProtoMessage() {} func (*RouteFeeRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_7a0613f69d37b0a5, []int{2} + return fileDescriptor_7a0613f69d37b0a5, []int{3} } func (m *RouteFeeRequest) XXX_Unmarshal(b []byte) error { @@ -375,7 +453,7 @@ func (m *RouteFeeResponse) Reset() { *m = RouteFeeResponse{} } func (m *RouteFeeResponse) String() string { return proto.CompactTextString(m) } func (*RouteFeeResponse) ProtoMessage() {} func (*RouteFeeResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_7a0613f69d37b0a5, []int{3} + return fileDescriptor_7a0613f69d37b0a5, []int{4} } func (m *RouteFeeResponse) XXX_Unmarshal(b []byte) error { @@ -424,7 +502,7 @@ func (m *SendToRouteRequest) Reset() { *m = SendToRouteRequest{} } func (m *SendToRouteRequest) String() string { return proto.CompactTextString(m) } func (*SendToRouteRequest) ProtoMessage() {} func (*SendToRouteRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_7a0613f69d37b0a5, []int{4} + return fileDescriptor_7a0613f69d37b0a5, []int{5} } func (m *SendToRouteRequest) XXX_Unmarshal(b []byte) error { @@ -473,7 +551,7 @@ func (m *SendToRouteResponse) Reset() { *m = SendToRouteResponse{} } func (m *SendToRouteResponse) String() string { return proto.CompactTextString(m) } func (*SendToRouteResponse) ProtoMessage() {} func (*SendToRouteResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_7a0613f69d37b0a5, []int{5} + return fileDescriptor_7a0613f69d37b0a5, []int{6} } func (m *SendToRouteResponse) XXX_Unmarshal(b []byte) error { @@ -534,7 +612,7 @@ func (m *Failure) Reset() { *m = Failure{} } func (m *Failure) String() string { return proto.CompactTextString(m) } func (*Failure) ProtoMessage() {} func (*Failure) Descriptor() ([]byte, []int) { - return fileDescriptor_7a0613f69d37b0a5, []int{6} + return fileDescriptor_7a0613f69d37b0a5, []int{7} } func (m *Failure) XXX_Unmarshal(b []byte) error { @@ -671,7 +749,7 @@ func (m *ChannelUpdate) Reset() { *m = ChannelUpdate{} } func (m *ChannelUpdate) String() string { return proto.CompactTextString(m) } func (*ChannelUpdate) ProtoMessage() {} func (*ChannelUpdate) Descriptor() ([]byte, []int) { - return fileDescriptor_7a0613f69d37b0a5, []int{7} + return fileDescriptor_7a0613f69d37b0a5, []int{8} } func (m *ChannelUpdate) XXX_Unmarshal(b []byte) error { @@ -786,7 +864,7 @@ func (m *ResetMissionControlRequest) Reset() { *m = ResetMissionControlR func (m *ResetMissionControlRequest) String() string { return proto.CompactTextString(m) } func (*ResetMissionControlRequest) ProtoMessage() {} func (*ResetMissionControlRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_7a0613f69d37b0a5, []int{8} + return fileDescriptor_7a0613f69d37b0a5, []int{9} } func (m *ResetMissionControlRequest) XXX_Unmarshal(b []byte) error { @@ -817,7 +895,7 @@ func (m *ResetMissionControlResponse) Reset() { *m = ResetMissionControl func (m *ResetMissionControlResponse) String() string { return proto.CompactTextString(m) } func (*ResetMissionControlResponse) ProtoMessage() {} func (*ResetMissionControlResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_7a0613f69d37b0a5, []int{9} + return fileDescriptor_7a0613f69d37b0a5, []int{10} } func (m *ResetMissionControlResponse) XXX_Unmarshal(b []byte) error { @@ -848,7 +926,7 @@ func (m *QueryMissionControlRequest) Reset() { *m = QueryMissionControlR func (m *QueryMissionControlRequest) String() string { return proto.CompactTextString(m) } func (*QueryMissionControlRequest) ProtoMessage() {} func (*QueryMissionControlRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_7a0613f69d37b0a5, []int{10} + return fileDescriptor_7a0613f69d37b0a5, []int{11} } func (m *QueryMissionControlRequest) XXX_Unmarshal(b []byte) error { @@ -881,7 +959,7 @@ func (m *QueryMissionControlResponse) Reset() { *m = QueryMissionControl func (m *QueryMissionControlResponse) String() string { return proto.CompactTextString(m) } func (*QueryMissionControlResponse) ProtoMessage() {} func (*QueryMissionControlResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_7a0613f69d37b0a5, []int{11} + return fileDescriptor_7a0613f69d37b0a5, []int{12} } func (m *QueryMissionControlResponse) XXX_Unmarshal(b []byte) error { @@ -928,7 +1006,7 @@ func (m *NodeHistory) Reset() { *m = NodeHistory{} } func (m *NodeHistory) String() string { return proto.CompactTextString(m) } func (*NodeHistory) ProtoMessage() {} func (*NodeHistory) Descriptor() ([]byte, []int) { - return fileDescriptor_7a0613f69d37b0a5, []int{12} + return fileDescriptor_7a0613f69d37b0a5, []int{13} } func (m *NodeHistory) XXX_Unmarshal(b []byte) error { @@ -996,7 +1074,7 @@ func (m *ChannelHistory) Reset() { *m = ChannelHistory{} } func (m *ChannelHistory) String() string { return proto.CompactTextString(m) } func (*ChannelHistory) ProtoMessage() {} func (*ChannelHistory) Descriptor() ([]byte, []int) { - return fileDescriptor_7a0613f69d37b0a5, []int{13} + return fileDescriptor_7a0613f69d37b0a5, []int{14} } func (m *ChannelHistory) XXX_Unmarshal(b []byte) error { @@ -1046,9 +1124,11 @@ func (m *ChannelHistory) GetSuccessProb() float32 { } func init() { + proto.RegisterEnum("routerrpc.PaymentState", PaymentState_name, PaymentState_value) proto.RegisterEnum("routerrpc.Failure_FailureCode", Failure_FailureCode_name, Failure_FailureCode_value) - proto.RegisterType((*PaymentRequest)(nil), "routerrpc.PaymentRequest") - proto.RegisterType((*PaymentResponse)(nil), "routerrpc.PaymentResponse") + proto.RegisterType((*SendPaymentRequest)(nil), "routerrpc.SendPaymentRequest") + proto.RegisterType((*TrackPaymentRequest)(nil), "routerrpc.TrackPaymentRequest") + proto.RegisterType((*PaymentStatus)(nil), "routerrpc.PaymentStatus") proto.RegisterType((*RouteFeeRequest)(nil), "routerrpc.RouteFeeRequest") proto.RegisterType((*RouteFeeResponse)(nil), "routerrpc.RouteFeeResponse") proto.RegisterType((*SendToRouteRequest)(nil), "routerrpc.SendToRouteRequest") @@ -1066,101 +1146,106 @@ func init() { func init() { proto.RegisterFile("routerrpc/router.proto", fileDescriptor_7a0613f69d37b0a5) } var fileDescriptor_7a0613f69d37b0a5 = []byte{ - // 1503 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x57, 0xdd, 0x72, 0xda, 0xce, - 0x15, 0x2f, 0x06, 0x1b, 0x38, 0x7c, 0xc9, 0xeb, 0x8f, 0x60, 0x6c, 0xe7, 0xef, 0xa8, 0x6d, 0xc2, - 0x64, 0x32, 0xf6, 0x94, 0x4e, 0x32, 0xbd, 0x6a, 0x87, 0x80, 0xa8, 0x35, 0x06, 0xe1, 0x2c, 0xe0, - 0xc4, 0xed, 0xc5, 0xce, 0x1a, 0xad, 0x41, 0xb5, 0x90, 0x14, 0x69, 0x49, 0x43, 0x1f, 0xa0, 0xaf, - 0xd3, 0xde, 0xf4, 0xb6, 0x17, 0x7d, 0x8b, 0xbe, 0x4d, 0x67, 0x77, 0xc5, 0x97, 0x8d, 0xd3, 0xff, - 0x95, 0xd1, 0xef, 0xfc, 0xf6, 0x7c, 0x9f, 0xb3, 0x6b, 0x38, 0x0c, 0xfd, 0x29, 0x67, 0x61, 0x18, - 0x0c, 0x2f, 0xd4, 0xaf, 0xf3, 0x20, 0xf4, 0xb9, 0x8f, 0xb2, 0x0b, 0xbc, 0x92, 0x0d, 0x83, 0xa1, - 0x42, 0xf5, 0xff, 0x6c, 0x41, 0xf1, 0x9a, 0xce, 0x26, 0xcc, 0xe3, 0x98, 0x7d, 0x9d, 0xb2, 0x88, - 0x23, 0x04, 0x29, 0x9b, 0x45, 0xbc, 0x9c, 0x38, 0x4b, 0x54, 0xf3, 0x58, 0xfe, 0x46, 0x1a, 0x24, - 0xe9, 0x84, 0x97, 0xb7, 0xce, 0x12, 0xd5, 0x24, 0x16, 0x3f, 0xd1, 0x2b, 0xc8, 0x07, 0xea, 0x1c, - 0x19, 0xd3, 0x68, 0x5c, 0x4e, 0x4a, 0x76, 0x2e, 0xc6, 0x2e, 0x69, 0x34, 0x46, 0x55, 0xd0, 0xee, - 0x1d, 0x8f, 0xba, 0x64, 0xe8, 0xf2, 0x6f, 0xc4, 0x66, 0x2e, 0xa7, 0xe5, 0xd4, 0x59, 0xa2, 0xba, - 0x8d, 0x8b, 0x12, 0x6f, 0xb8, 0xfc, 0x5b, 0x53, 0xa0, 0xe8, 0x0d, 0x94, 0xe6, 0xca, 0x42, 0xe5, - 0x45, 0x79, 0xfb, 0x2c, 0x51, 0xcd, 0xe2, 0x62, 0xb0, 0xee, 0xdb, 0x1b, 0x28, 0x71, 0x67, 0xc2, - 0xfc, 0x29, 0x27, 0x11, 0x1b, 0xfa, 0x9e, 0x1d, 0x95, 0x77, 0x94, 0xc6, 0x18, 0xee, 0x29, 0x14, - 0xe9, 0x50, 0xb8, 0x67, 0x8c, 0xb8, 0xce, 0xc4, 0xe1, 0x24, 0xa2, 0xbc, 0x9c, 0x96, 0xae, 0xe7, - 0xee, 0x19, 0x6b, 0x0b, 0xac, 0x47, 0xb9, 0xf0, 0xcf, 0x9f, 0xf2, 0x91, 0xef, 0x78, 0x23, 0x32, - 0x1c, 0x53, 0x8f, 0x38, 0x76, 0x39, 0x73, 0x96, 0xa8, 0xa6, 0x70, 0x71, 0x8e, 0x37, 0xc6, 0xd4, - 0x33, 0x6d, 0x74, 0x0a, 0x20, 0x63, 0x90, 0xea, 0xca, 0x59, 0x69, 0x31, 0x2b, 0x10, 0xa9, 0x4b, - 0xff, 0x0b, 0x94, 0x16, 0x39, 0x8c, 0x02, 0xdf, 0x8b, 0x18, 0x3a, 0x82, 0x4c, 0x40, 0x67, 0x2a, - 0x35, 0x2a, 0x91, 0xe9, 0x80, 0xce, 0x64, 0x5a, 0x8e, 0x21, 0x1b, 0x84, 0x8c, 0x38, 0x13, 0x3a, - 0x62, 0x32, 0xa3, 0x79, 0x9c, 0x09, 0x42, 0x66, 0x8a, 0x6f, 0xf4, 0x13, 0xcc, 0x53, 0x48, 0x58, - 0x18, 0xca, 0xac, 0x66, 0x31, 0xc4, 0x90, 0x11, 0x86, 0xfa, 0xef, 0xa1, 0x84, 0x45, 0x21, 0x5b, - 0x8c, 0xfd, 0xa8, 0x60, 0x2f, 0x20, 0x4d, 0x27, 0x2a, 0x72, 0x55, 0xb4, 0x1d, 0x3a, 0x11, 0x41, - 0xeb, 0x36, 0x68, 0xcb, 0xf3, 0xb1, 0xb3, 0x55, 0xd0, 0x44, 0x73, 0x88, 0x3c, 0x88, 0xa4, 0x4d, - 0xc4, 0xa9, 0x84, 0x3c, 0x55, 0x8c, 0xf1, 0x16, 0x63, 0x9d, 0x88, 0x72, 0xf4, 0x5a, 0xe5, 0x9f, - 0xb8, 0xfe, 0xf0, 0x41, 0x54, 0x94, 0xce, 0x62, 0xf5, 0x05, 0x01, 0xb7, 0xfd, 0xe1, 0x43, 0x53, - 0x80, 0xfa, 0x9f, 0x01, 0xf5, 0x98, 0x67, 0xf7, 0x7d, 0x69, 0x6b, 0xee, 0xe8, 0xe3, 0x9e, 0x49, - 0x3c, 0xed, 0x19, 0x1d, 0xb6, 0x65, 0x9f, 0x4a, 0xb5, 0xb9, 0x5a, 0xfe, 0xdc, 0xf5, 0x44, 0xb3, - 0x2a, 0x35, 0x4a, 0xa4, 0x13, 0xd8, 0x5b, 0x53, 0x1e, 0x47, 0x51, 0x01, 0x91, 0x46, 0x95, 0xd6, - 0xc4, 0x22, 0xad, 0xf2, 0x1b, 0xbd, 0x83, 0xf4, 0x3d, 0x75, 0xdc, 0x69, 0x38, 0x57, 0x8c, 0xce, - 0x17, 0xe3, 0x70, 0xde, 0x52, 0x12, 0x3c, 0xa7, 0xe8, 0x7f, 0x4f, 0x43, 0x3a, 0x06, 0x51, 0x0d, - 0x52, 0x43, 0xdf, 0x56, 0x1a, 0x8b, 0xb5, 0x97, 0x4f, 0x8f, 0xcd, 0xff, 0x36, 0x7c, 0x9b, 0x61, - 0xc9, 0x45, 0x35, 0x38, 0x88, 0x55, 0x91, 0xc8, 0x9f, 0x86, 0x43, 0x46, 0x82, 0xe9, 0xdd, 0x03, - 0x9b, 0xc5, 0xd5, 0xde, 0x8b, 0x85, 0x3d, 0x29, 0xbb, 0x96, 0x22, 0xf4, 0x07, 0x28, 0x8a, 0x1e, - 0xf4, 0x98, 0x4b, 0xa6, 0x81, 0x4d, 0x39, 0x93, 0xb5, 0xcf, 0xd5, 0xca, 0x2b, 0x16, 0x1b, 0x8a, - 0x30, 0x90, 0x72, 0x5c, 0x18, 0xae, 0x7e, 0x8a, 0xb6, 0x1a, 0x73, 0x77, 0xa8, 0xaa, 0x97, 0x92, - 0x6d, 0x9c, 0x11, 0x80, 0xac, 0x9b, 0x0e, 0x05, 0xdf, 0x73, 0x7c, 0x8f, 0x44, 0x63, 0x4a, 0x6a, - 0xef, 0x3f, 0xc8, 0xf1, 0xca, 0xe3, 0x9c, 0x04, 0x7b, 0x63, 0x5a, 0x7b, 0xff, 0x41, 0xb4, 0x9e, - 0x6c, 0x72, 0xf6, 0x3d, 0x70, 0xc2, 0x99, 0x9c, 0xab, 0x02, 0x96, 0x7d, 0x6f, 0x48, 0x04, 0xed, - 0xc3, 0xf6, 0xbd, 0x4b, 0x47, 0x91, 0x9c, 0xa5, 0x02, 0x56, 0x1f, 0xfa, 0x7f, 0x53, 0x90, 0x5b, - 0x49, 0x01, 0xca, 0x43, 0x06, 0x1b, 0x3d, 0x03, 0xdf, 0x18, 0x4d, 0xed, 0x17, 0xa8, 0x0c, 0xfb, - 0x03, 0xeb, 0xca, 0xea, 0x7e, 0xb6, 0xc8, 0x75, 0xfd, 0xb6, 0x63, 0x58, 0x7d, 0x72, 0x59, 0xef, - 0x5d, 0x6a, 0x09, 0x74, 0x02, 0x65, 0xd3, 0x6a, 0x74, 0x31, 0x36, 0x1a, 0xfd, 0x85, 0xac, 0xde, - 0xe9, 0x0e, 0xac, 0xbe, 0xb6, 0x85, 0x7e, 0x82, 0xe3, 0x96, 0x69, 0xd5, 0xdb, 0x64, 0xc9, 0x69, - 0xb4, 0xfb, 0x37, 0xc4, 0xf8, 0x72, 0x6d, 0xe2, 0x5b, 0x2d, 0xb9, 0x89, 0x70, 0xd9, 0x6f, 0x37, - 0xe6, 0x1a, 0x52, 0xe8, 0x08, 0x0e, 0x14, 0x41, 0x1d, 0x21, 0xfd, 0x6e, 0x97, 0xf4, 0xba, 0x5d, - 0x4b, 0xdb, 0x46, 0xbb, 0x50, 0x30, 0xad, 0x9b, 0x7a, 0xdb, 0x6c, 0x12, 0x6c, 0xd4, 0xdb, 0x1d, - 0x6d, 0x07, 0xed, 0x41, 0xe9, 0x31, 0x2f, 0x2d, 0x54, 0xcc, 0x79, 0x5d, 0xcb, 0xec, 0x5a, 0xe4, - 0xc6, 0xc0, 0x3d, 0xb3, 0x6b, 0x69, 0x19, 0x74, 0x08, 0x68, 0x5d, 0x74, 0xd9, 0xa9, 0x37, 0xb4, - 0x2c, 0x3a, 0x80, 0xdd, 0x75, 0xfc, 0xca, 0xb8, 0xd5, 0x40, 0xa4, 0x41, 0x39, 0x46, 0x3e, 0x1a, - 0xed, 0xee, 0x67, 0xd2, 0x31, 0x2d, 0xb3, 0x33, 0xe8, 0x68, 0x39, 0xb4, 0x0f, 0x5a, 0xcb, 0x30, - 0x88, 0x69, 0xf5, 0x06, 0xad, 0x96, 0xd9, 0x30, 0x0d, 0xab, 0xaf, 0xe5, 0x95, 0xe5, 0x4d, 0x81, - 0x17, 0xc4, 0x81, 0xc6, 0x65, 0xdd, 0xb2, 0x8c, 0x36, 0x69, 0x9a, 0xbd, 0xfa, 0xc7, 0xb6, 0xd1, - 0xd4, 0x8a, 0xe8, 0x14, 0x8e, 0xfa, 0x46, 0xe7, 0xba, 0x8b, 0xeb, 0xf8, 0x96, 0xcc, 0xe5, 0xad, - 0xba, 0xd9, 0x1e, 0x60, 0x43, 0x2b, 0xa1, 0x57, 0x70, 0x8a, 0x8d, 0x4f, 0x03, 0x13, 0x1b, 0x4d, - 0x62, 0x75, 0x9b, 0x06, 0x69, 0x19, 0xf5, 0xfe, 0x00, 0x1b, 0xa4, 0x63, 0xf6, 0x7a, 0xa6, 0xf5, - 0x47, 0x4d, 0x43, 0xbf, 0x82, 0xb3, 0x05, 0x65, 0xa1, 0xe0, 0x11, 0x6b, 0x57, 0xc4, 0x37, 0xaf, - 0xa7, 0x65, 0x7c, 0xe9, 0x93, 0x6b, 0xc3, 0xc0, 0x1a, 0x42, 0x15, 0x38, 0x5c, 0x9a, 0x57, 0x06, - 0x62, 0xdb, 0x7b, 0x42, 0x76, 0x6d, 0xe0, 0x4e, 0xdd, 0x12, 0x05, 0x5e, 0x93, 0xed, 0x0b, 0xb7, - 0x97, 0xb2, 0xc7, 0x6e, 0x1f, 0xe8, 0xff, 0x48, 0x42, 0x61, 0xad, 0xe9, 0xd1, 0x09, 0x64, 0x23, - 0x67, 0xe4, 0x51, 0x2e, 0x46, 0x59, 0x4d, 0xf9, 0x12, 0x90, 0x7b, 0x7a, 0x4c, 0x1d, 0x4f, 0xad, - 0x17, 0x35, 0x6d, 0x59, 0x89, 0xc8, 0xe5, 0xf2, 0x02, 0xd2, 0xf3, 0x3d, 0x9f, 0x94, 0x03, 0xb2, - 0x33, 0x54, 0xfb, 0xfd, 0x04, 0xb2, 0x62, 0x7f, 0x45, 0x9c, 0x4e, 0x02, 0x39, 0x3b, 0x05, 0xbc, - 0x04, 0xd0, 0x2f, 0xa1, 0x30, 0x61, 0x51, 0x44, 0x47, 0x8c, 0xa8, 0xfe, 0x07, 0xc9, 0xc8, 0xc7, - 0x60, 0x4b, 0x60, 0x82, 0x34, 0x9f, 0x5f, 0x45, 0xda, 0x56, 0xa4, 0x18, 0x54, 0xa4, 0xc7, 0xeb, - 0x93, 0xd3, 0x78, 0xcc, 0x56, 0xd7, 0x27, 0xa7, 0xe8, 0x2d, 0xec, 0xaa, 0x59, 0x76, 0x3c, 0x67, - 0x32, 0x9d, 0xa8, 0x99, 0x4e, 0x4b, 0x97, 0x4b, 0x72, 0xa6, 0x15, 0x2e, 0x47, 0xfb, 0x08, 0x32, - 0x77, 0x34, 0x62, 0x62, 0x73, 0xcb, 0xdb, 0xab, 0x80, 0xd3, 0xe2, 0xbb, 0xc5, 0xe4, 0x25, 0x24, - 0xf6, 0x79, 0x28, 0xb6, 0x49, 0x56, 0x89, 0xee, 0x19, 0xc3, 0x22, 0x8f, 0x0b, 0x0b, 0xf4, 0xfb, - 0xd2, 0x42, 0x6e, 0xc5, 0x82, 0xc2, 0xa5, 0x85, 0xb7, 0xb0, 0xcb, 0xbe, 0xf3, 0x90, 0x12, 0x3f, - 0xa0, 0x5f, 0xa7, 0x8c, 0xd8, 0x94, 0xd3, 0x72, 0x5e, 0x26, 0xb7, 0x24, 0x05, 0x5d, 0x89, 0x37, - 0x29, 0xa7, 0xfa, 0x09, 0x54, 0x30, 0x8b, 0x18, 0xef, 0x38, 0x51, 0xe4, 0xf8, 0x5e, 0xc3, 0xf7, - 0x78, 0xe8, 0xbb, 0xf1, 0x05, 0xa0, 0x9f, 0xc2, 0xf1, 0x46, 0xa9, 0xda, 0xe0, 0xe2, 0xf0, 0xa7, - 0x29, 0x0b, 0x67, 0x9b, 0x0f, 0x5f, 0xc1, 0xf1, 0x46, 0x69, 0xbc, 0xfe, 0xdf, 0xc1, 0xb6, 0xe7, - 0xdb, 0x2c, 0x2a, 0x27, 0xce, 0x92, 0xd5, 0x5c, 0xed, 0x70, 0x65, 0x6f, 0x5a, 0xbe, 0xcd, 0x2e, - 0x9d, 0x88, 0xfb, 0xe1, 0x0c, 0x2b, 0x92, 0xfe, 0xef, 0x04, 0xe4, 0x56, 0x60, 0x74, 0x08, 0x3b, - 0xf1, 0x8e, 0x56, 0x4d, 0x15, 0x7f, 0xa1, 0xd7, 0x50, 0x74, 0x69, 0xc4, 0x89, 0x58, 0xd9, 0x44, - 0x14, 0x29, 0xbe, 0xef, 0x1e, 0xa1, 0xe8, 0x77, 0xf0, 0xc2, 0xe7, 0x63, 0x16, 0xaa, 0x87, 0x44, - 0x34, 0x1d, 0x0e, 0x59, 0x14, 0x91, 0x20, 0xf4, 0xef, 0x64, 0xab, 0x6d, 0xe1, 0xe7, 0xc4, 0xe8, - 0x3d, 0x64, 0xe2, 0x1e, 0x89, 0xca, 0x29, 0xe9, 0xfa, 0xd1, 0xd3, 0x95, 0x3f, 0xf7, 0x7e, 0x41, - 0xd5, 0xff, 0x99, 0x80, 0xe2, 0xba, 0x10, 0xbd, 0x94, 0xdd, 0x2f, 0x5b, 0xd0, 0xb1, 0x65, 0x1c, - 0x29, 0xbc, 0x82, 0xfc, 0xec, 0x58, 0x6a, 0xb0, 0x3f, 0x71, 0x3c, 0x12, 0x30, 0x8f, 0xba, 0xce, - 0xdf, 0x18, 0x99, 0x3f, 0x24, 0x92, 0x92, 0xbd, 0x51, 0x86, 0x74, 0xc8, 0xaf, 0x05, 0x9d, 0x92, - 0x41, 0xaf, 0x61, 0xb5, 0x7f, 0x25, 0x61, 0x47, 0x5e, 0xd9, 0x21, 0x6a, 0x42, 0x4e, 0x5c, 0xe1, - 0xf1, 0xab, 0x09, 0xad, 0x46, 0xbc, 0xfe, 0x1a, 0xad, 0x54, 0x36, 0x89, 0xe2, 0x92, 0x5f, 0x81, - 0x66, 0x44, 0xdc, 0x99, 0x88, 0xdb, 0x30, 0x7e, 0xd3, 0xa0, 0x55, 0xfe, 0xa3, 0x87, 0x52, 0xe5, - 0x78, 0xa3, 0x2c, 0x56, 0xd6, 0x56, 0x2e, 0xc5, 0xaf, 0x0a, 0x74, 0xba, 0xc2, 0x7d, 0xfa, 0x94, - 0xa9, 0xbc, 0x7c, 0x4e, 0x1c, 0x6b, 0xb3, 0x61, 0x6f, 0x43, 0xa7, 0xa3, 0x5f, 0xaf, 0x7a, 0xf0, - 0xec, 0x9c, 0x54, 0x5e, 0xff, 0x3f, 0xda, 0xd2, 0xca, 0x86, 0x91, 0x58, 0xb3, 0xf2, 0xfc, 0x40, - 0xad, 0x59, 0xf9, 0xc1, 0x64, 0x7d, 0xfc, 0xcd, 0x9f, 0x2e, 0x46, 0x0e, 0x1f, 0x4f, 0xef, 0xce, - 0x87, 0xfe, 0xe4, 0xc2, 0x75, 0x46, 0x63, 0xee, 0x39, 0xde, 0xc8, 0x63, 0xfc, 0xaf, 0x7e, 0xf8, - 0x70, 0xe1, 0x7a, 0xf6, 0x85, 0x7c, 0xa5, 0x5d, 0x2c, 0xd4, 0xdd, 0xed, 0xc8, 0xff, 0x2e, 0x7e, - 0xfb, 0xbf, 0x00, 0x00, 0x00, 0xff, 0xff, 0x15, 0x95, 0x7d, 0xcd, 0x8d, 0x0c, 0x00, 0x00, + // 1575 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x57, 0xdd, 0x72, 0x22, 0xc7, + 0x15, 0x36, 0x02, 0x09, 0x71, 0xf8, 0xd1, 0xa8, 0xa5, 0xd5, 0xb2, 0x68, 0xb5, 0x96, 0x27, 0xc9, + 0x5a, 0xb5, 0xe5, 0x48, 0x09, 0xa9, 0x75, 0xf9, 0x2a, 0x29, 0x16, 0x1a, 0x33, 0x59, 0x98, 0x91, + 0x1b, 0x58, 0x5b, 0xc9, 0x45, 0x57, 0x0b, 0x5a, 0x30, 0x25, 0x98, 0xc1, 0xd3, 0x8d, 0xb3, 0xca, + 0x45, 0xee, 0x92, 0xd7, 0x49, 0x9e, 0x20, 0x97, 0x79, 0x87, 0xbc, 0x4d, 0xaa, 0xbb, 0x07, 0x18, + 0x10, 0xda, 0xf8, 0x4a, 0xcc, 0x77, 0xbe, 0x3e, 0xe7, 0xf4, 0xf9, 0xeb, 0x23, 0x38, 0x89, 0xc2, + 0xb9, 0xe4, 0x51, 0x34, 0x1b, 0x5c, 0x99, 0x5f, 0x97, 0xb3, 0x28, 0x94, 0x21, 0xca, 0x2d, 0xf1, + 0x4a, 0x2e, 0x9a, 0x0d, 0x0c, 0x6a, 0xff, 0x67, 0x07, 0x50, 0x97, 0x07, 0xc3, 0x6b, 0xf6, 0x30, + 0xe5, 0x81, 0x24, 0xfc, 0xc7, 0x39, 0x17, 0x12, 0x21, 0xc8, 0x0c, 0xb9, 0x90, 0xe5, 0xd4, 0x79, + 0xea, 0xa2, 0x40, 0xf4, 0x6f, 0x64, 0x41, 0x9a, 0x4d, 0x65, 0x79, 0xe7, 0x3c, 0x75, 0x91, 0x26, + 0xea, 0x27, 0xfa, 0x02, 0x0a, 0x33, 0x73, 0x8e, 0x8e, 0x99, 0x18, 0x97, 0xd3, 0x9a, 0x9d, 0x8f, + 0xb1, 0x16, 0x13, 0x63, 0x74, 0x01, 0xd6, 0x9d, 0x1f, 0xb0, 0x09, 0x1d, 0x4c, 0xe4, 0x4f, 0x74, + 0xc8, 0x27, 0x92, 0x95, 0x33, 0xe7, 0xa9, 0x8b, 0x5d, 0x52, 0xd2, 0x78, 0x7d, 0x22, 0x7f, 0x6a, + 0x28, 0x14, 0x7d, 0x09, 0x07, 0x0b, 0x65, 0x91, 0xf1, 0xa2, 0xbc, 0x7b, 0x9e, 0xba, 0xc8, 0x91, + 0xd2, 0x6c, 0xdd, 0xb7, 0x2f, 0xe1, 0x40, 0xfa, 0x53, 0x1e, 0xce, 0x25, 0x15, 0x7c, 0x10, 0x06, + 0x43, 0x51, 0xde, 0x33, 0x1a, 0x63, 0xb8, 0x6b, 0x50, 0x64, 0x43, 0xf1, 0x8e, 0x73, 0x3a, 0xf1, + 0xa7, 0xbe, 0xa4, 0x82, 0xc9, 0x72, 0x56, 0xbb, 0x9e, 0xbf, 0xe3, 0xbc, 0xad, 0xb0, 0x2e, 0x93, + 0xca, 0xbf, 0x70, 0x2e, 0x47, 0xa1, 0x1f, 0x8c, 0xe8, 0x60, 0xcc, 0x02, 0xea, 0x0f, 0xcb, 0xfb, + 0xe7, 0xa9, 0x8b, 0x0c, 0x29, 0x2d, 0xf0, 0xfa, 0x98, 0x05, 0xce, 0x10, 0x9d, 0x01, 0xe8, 0x3b, + 0x68, 0x75, 0xe5, 0x9c, 0xb6, 0x98, 0x53, 0x88, 0xd6, 0x65, 0x7f, 0x03, 0x47, 0xbd, 0x88, 0x0d, + 0xee, 0x37, 0x02, 0xb9, 0x19, 0xa2, 0xd4, 0xa3, 0x10, 0xd9, 0x7f, 0x83, 0x62, 0x7c, 0xa8, 0x2b, + 0x99, 0x9c, 0x0b, 0xf4, 0x6b, 0xd8, 0x15, 0x92, 0x49, 0xae, 0xc9, 0xa5, 0xea, 0xf3, 0xcb, 0x65, + 0xe6, 0x2e, 0x13, 0x44, 0x4e, 0x0c, 0x0b, 0x55, 0x60, 0x7f, 0x16, 0x71, 0x7f, 0xca, 0x46, 0x5c, + 0x27, 0xa7, 0x40, 0x96, 0xdf, 0xc8, 0x86, 0x5d, 0x7d, 0x58, 0xa7, 0x26, 0x5f, 0x2d, 0x5c, 0x4e, + 0x02, 0xa5, 0x86, 0x28, 0x8c, 0x18, 0x91, 0xfd, 0x7b, 0x38, 0xd0, 0xdf, 0x4d, 0xce, 0x3f, 0x95, + 0xfe, 0xe7, 0x90, 0x65, 0x53, 0x13, 0x47, 0x53, 0x02, 0x7b, 0x6c, 0xaa, 0x42, 0x68, 0x0f, 0xc1, + 0x5a, 0x9d, 0x17, 0xb3, 0x30, 0x10, 0x5c, 0x85, 0x55, 0x29, 0x57, 0x51, 0x55, 0x29, 0x98, 0xaa, + 0x53, 0x29, 0x7d, 0xaa, 0x14, 0xe3, 0x4d, 0xce, 0x3b, 0x82, 0x49, 0xf4, 0xda, 0x64, 0x93, 0x4e, + 0xc2, 0xc1, 0xbd, 0xaa, 0x0f, 0xf6, 0x10, 0xab, 0x2f, 0x2a, 0xb8, 0x1d, 0x0e, 0xee, 0x1b, 0x0a, + 0xb4, 0xff, 0x6c, 0xea, 0xb4, 0x17, 0x1a, 0xdf, 0x7f, 0x76, 0x78, 0x57, 0x21, 0xd8, 0x79, 0x3a, + 0x04, 0x14, 0x8e, 0xd6, 0x94, 0xc7, 0xb7, 0x48, 0x46, 0x36, 0xb5, 0x11, 0xd9, 0xaf, 0x20, 0x7b, + 0xc7, 0xfc, 0xc9, 0x3c, 0x5a, 0x28, 0x46, 0x89, 0x34, 0x35, 0x8d, 0x84, 0x2c, 0x28, 0xf6, 0x3f, + 0xb2, 0x90, 0x8d, 0x41, 0x54, 0x85, 0xcc, 0x20, 0x1c, 0x2e, 0xb2, 0xfb, 0xea, 0xf1, 0xb1, 0xc5, + 0xdf, 0x7a, 0x38, 0xe4, 0x44, 0x73, 0x51, 0x15, 0x9e, 0xc5, 0xaa, 0xa8, 0x08, 0xe7, 0xd1, 0x80, + 0xd3, 0xd9, 0xfc, 0xf6, 0x9e, 0x3f, 0xc4, 0x09, 0x3f, 0x8a, 0x85, 0x5d, 0x2d, 0xbb, 0xd6, 0x22, + 0xf4, 0x07, 0x28, 0xa9, 0x8a, 0x0e, 0xf8, 0x84, 0xce, 0x67, 0x43, 0xb6, 0x2c, 0x82, 0x72, 0xc2, + 0x62, 0xdd, 0x10, 0xfa, 0x5a, 0x4e, 0x8a, 0x83, 0xe4, 0x27, 0x3a, 0x85, 0xdc, 0x58, 0x4e, 0x06, + 0x26, 0x7b, 0x19, 0xdd, 0x14, 0xfb, 0x0a, 0xd0, 0x79, 0xb3, 0xa1, 0x18, 0x06, 0x7e, 0x18, 0x50, + 0x31, 0x66, 0xb4, 0xfa, 0xf6, 0x6b, 0xdd, 0xac, 0x05, 0x92, 0xd7, 0x60, 0x77, 0xcc, 0xaa, 0x6f, + 0xbf, 0x46, 0x9f, 0x43, 0x5e, 0xb7, 0x0c, 0xff, 0x38, 0xf3, 0xa3, 0x07, 0xdd, 0xa5, 0x45, 0xa2, + 0xbb, 0x08, 0x6b, 0x04, 0x1d, 0xc3, 0xee, 0xdd, 0x84, 0x8d, 0x84, 0xee, 0xcc, 0x22, 0x31, 0x1f, + 0xf6, 0x7f, 0x33, 0x90, 0x4f, 0x84, 0x00, 0x15, 0x60, 0x9f, 0xe0, 0x2e, 0x26, 0x1f, 0x70, 0xc3, + 0xfa, 0x0c, 0x95, 0xe1, 0xb8, 0xef, 0xbe, 0x77, 0xbd, 0xef, 0x5d, 0x7a, 0x5d, 0xbb, 0xe9, 0x60, + 0xb7, 0x47, 0x5b, 0xb5, 0x6e, 0xcb, 0x4a, 0xa1, 0x97, 0x50, 0x76, 0xdc, 0xba, 0x47, 0x08, 0xae, + 0xf7, 0x96, 0xb2, 0x5a, 0xc7, 0xeb, 0xbb, 0x3d, 0x6b, 0x07, 0x7d, 0x0e, 0xa7, 0x4d, 0xc7, 0xad, + 0xb5, 0xe9, 0x8a, 0x53, 0x6f, 0xf7, 0x3e, 0x50, 0xfc, 0xc3, 0xb5, 0x43, 0x6e, 0xac, 0xf4, 0x36, + 0x42, 0xab, 0xd7, 0xae, 0x2f, 0x34, 0x64, 0xd0, 0x0b, 0x78, 0x66, 0x08, 0xe6, 0x08, 0xed, 0x79, + 0x1e, 0xed, 0x7a, 0x9e, 0x6b, 0xed, 0xa2, 0x43, 0x28, 0x3a, 0xee, 0x87, 0x5a, 0xdb, 0x69, 0x50, + 0x82, 0x6b, 0xed, 0x8e, 0xb5, 0x87, 0x8e, 0xe0, 0x60, 0x93, 0x97, 0x55, 0x2a, 0x16, 0x3c, 0xcf, + 0x75, 0x3c, 0x97, 0x7e, 0xc0, 0xa4, 0xeb, 0x78, 0xae, 0xb5, 0x8f, 0x4e, 0x00, 0xad, 0x8b, 0x5a, + 0x9d, 0x5a, 0xdd, 0xca, 0xa1, 0x67, 0x70, 0xb8, 0x8e, 0xbf, 0xc7, 0x37, 0x16, 0xa8, 0x30, 0x18, + 0xc7, 0xe8, 0x3b, 0xdc, 0xf6, 0xbe, 0xa7, 0x1d, 0xc7, 0x75, 0x3a, 0xfd, 0x8e, 0x95, 0x47, 0xc7, + 0x60, 0x35, 0x31, 0xa6, 0x8e, 0xdb, 0xed, 0x37, 0x9b, 0x4e, 0xdd, 0xc1, 0x6e, 0xcf, 0x2a, 0x18, + 0xcb, 0xdb, 0x2e, 0x5e, 0x54, 0x07, 0xea, 0xad, 0x9a, 0xeb, 0xe2, 0x36, 0x6d, 0x38, 0xdd, 0xda, + 0xbb, 0x36, 0x6e, 0x58, 0x25, 0x74, 0x06, 0x2f, 0x7a, 0xb8, 0x73, 0xed, 0x91, 0x1a, 0xb9, 0xa1, + 0x0b, 0x79, 0xb3, 0xe6, 0xb4, 0xfb, 0x04, 0x5b, 0x07, 0xe8, 0x0b, 0x38, 0x23, 0xf8, 0xbb, 0xbe, + 0x43, 0x70, 0x83, 0xba, 0x5e, 0x03, 0xd3, 0x26, 0xae, 0xf5, 0xfa, 0x04, 0xd3, 0x8e, 0xd3, 0xed, + 0x3a, 0xee, 0xb7, 0x96, 0x85, 0x7e, 0x09, 0xe7, 0x4b, 0xca, 0x52, 0xc1, 0x06, 0xeb, 0x50, 0xdd, + 0x6f, 0x91, 0x4f, 0x17, 0xff, 0xd0, 0xa3, 0xd7, 0x18, 0x13, 0x0b, 0xa1, 0x0a, 0x9c, 0xac, 0xcc, + 0x1b, 0x03, 0xb1, 0xed, 0x23, 0x25, 0xbb, 0xc6, 0xa4, 0x53, 0x73, 0x55, 0x82, 0xd7, 0x64, 0xc7, + 0xca, 0xed, 0x95, 0x6c, 0xd3, 0xed, 0x67, 0xf6, 0x3f, 0xd3, 0x50, 0x5c, 0x2b, 0x7a, 0xf4, 0x12, + 0x72, 0xc2, 0x1f, 0x05, 0x4c, 0xaa, 0x56, 0x36, 0x5d, 0xbe, 0x02, 0xf4, 0xd4, 0x1f, 0x33, 0x3f, + 0x30, 0xe3, 0xc5, 0x74, 0x5b, 0x4e, 0x23, 0x7a, 0xb8, 0x3c, 0x87, 0xec, 0xe2, 0xd5, 0x48, 0xeb, + 0x06, 0xd9, 0x1b, 0x98, 0xd7, 0xe2, 0x25, 0xe4, 0xd4, 0xfc, 0x12, 0x92, 0x4d, 0x67, 0xba, 0x77, + 0x8a, 0x64, 0x05, 0xa0, 0x5f, 0x40, 0x71, 0xca, 0x85, 0x60, 0x23, 0x4e, 0x4d, 0xfd, 0x83, 0x66, + 0x14, 0x62, 0xb0, 0xa9, 0x30, 0x45, 0x5a, 0xf4, 0xaf, 0x21, 0xed, 0x1a, 0x52, 0x0c, 0x1a, 0xd2, + 0xe6, 0xf8, 0x94, 0x2c, 0x6e, 0xb3, 0xe4, 0xf8, 0x94, 0x0c, 0xbd, 0x81, 0x43, 0xd3, 0xcb, 0x7e, + 0xe0, 0x4f, 0xe7, 0x53, 0xd3, 0xd3, 0x59, 0xed, 0xf2, 0x81, 0xee, 0x69, 0x83, 0xeb, 0xd6, 0x7e, + 0x01, 0xfb, 0xb7, 0x4c, 0x70, 0x35, 0xb9, 0xf5, 0x5b, 0x58, 0x24, 0x59, 0xf5, 0xdd, 0xe4, 0x5c, + 0x89, 0xd4, 0x3c, 0x8f, 0xd4, 0x34, 0xc9, 0x19, 0xd1, 0x1d, 0xe7, 0x44, 0xc5, 0x71, 0x69, 0x81, + 0x7d, 0x5c, 0x59, 0xc8, 0x27, 0x2c, 0x18, 0x5c, 0x5b, 0x78, 0x03, 0x87, 0xfc, 0xa3, 0x8c, 0x18, + 0x0d, 0x67, 0xec, 0xc7, 0x39, 0xa7, 0x43, 0x26, 0x59, 0xb9, 0xa0, 0x83, 0x7b, 0xa0, 0x05, 0x9e, + 0xc6, 0x1b, 0x4c, 0x32, 0xfb, 0x25, 0x54, 0x08, 0x17, 0x5c, 0x76, 0x7c, 0x21, 0xfc, 0x30, 0xa8, + 0x87, 0x81, 0x8c, 0xc2, 0x49, 0xfc, 0x00, 0xd8, 0x67, 0x70, 0xba, 0x55, 0x6a, 0x26, 0xb8, 0x3a, + 0xfc, 0xdd, 0x9c, 0x47, 0x0f, 0xdb, 0x0f, 0xbf, 0x87, 0xd3, 0xad, 0xd2, 0x78, 0xfc, 0x7f, 0x05, + 0xbb, 0x41, 0x38, 0xe4, 0xa2, 0x9c, 0x3a, 0x4f, 0x5f, 0xe4, 0xab, 0x27, 0x89, 0xb9, 0xe9, 0x86, + 0x43, 0xde, 0xf2, 0x85, 0x0c, 0xa3, 0x07, 0x62, 0x48, 0xf6, 0xbf, 0x53, 0x90, 0x4f, 0xc0, 0xe8, + 0x04, 0xf6, 0xe2, 0x19, 0x6d, 0x8a, 0x2a, 0xfe, 0x42, 0xaf, 0xa1, 0x34, 0x61, 0x42, 0x52, 0x35, + 0xb2, 0xa9, 0x4a, 0x52, 0xfc, 0xde, 0x6d, 0xa0, 0xe8, 0x1b, 0x78, 0x1e, 0xca, 0x31, 0x8f, 0xcc, + 0x5a, 0x22, 0xe6, 0x83, 0x01, 0x17, 0x82, 0xce, 0xa2, 0xf0, 0x56, 0x97, 0xda, 0x0e, 0x79, 0x4a, + 0x8c, 0xde, 0xc2, 0x7e, 0x5c, 0x23, 0xa2, 0x9c, 0xd1, 0xae, 0xbf, 0x78, 0x3c, 0xf2, 0x17, 0xde, + 0x2f, 0xa9, 0xf6, 0xbf, 0x52, 0x50, 0x5a, 0x17, 0xa2, 0x57, 0xba, 0xfa, 0x75, 0x09, 0xfa, 0x43, + 0x7d, 0x8f, 0x0c, 0x49, 0x20, 0x3f, 0xfb, 0x2e, 0x55, 0x38, 0x9e, 0xfa, 0x01, 0x9d, 0xf1, 0x80, + 0x4d, 0xfc, 0xbf, 0x72, 0xba, 0x58, 0x24, 0xd2, 0x9a, 0xbd, 0x55, 0x86, 0x6c, 0x28, 0xac, 0x5d, + 0x3a, 0xa3, 0x2f, 0xbd, 0x86, 0xbd, 0xe9, 0x43, 0x21, 0xb9, 0x11, 0xa1, 0x22, 0xe4, 0x1c, 0x97, + 0x36, 0xdb, 0xce, 0xb7, 0xad, 0x9e, 0xf5, 0x99, 0xfa, 0xec, 0xf6, 0xeb, 0x75, 0x8c, 0x1b, 0xb8, + 0x61, 0xa5, 0x10, 0x82, 0x92, 0x1a, 0x04, 0xb8, 0x41, 0x7b, 0x4e, 0x07, 0x7b, 0x7d, 0xf5, 0x2a, + 0x1c, 0xc1, 0x41, 0x8c, 0xb9, 0x1e, 0x25, 0x5e, 0xbf, 0x87, 0xad, 0x74, 0xf5, 0xef, 0x19, 0xd8, + 0xd3, 0x9b, 0x40, 0x84, 0x5a, 0x90, 0x4f, 0xac, 0xc7, 0xe8, 0x2c, 0x11, 0xc8, 0xc7, 0x6b, 0x73, + 0xa5, 0xbc, 0x7d, 0x55, 0x9b, 0x8b, 0xdf, 0xa4, 0xd0, 0x1f, 0xa1, 0x90, 0x5c, 0x10, 0x51, 0xf2, + 0xe1, 0xdf, 0xb2, 0x39, 0x7e, 0x52, 0xd7, 0x7b, 0xb0, 0xb0, 0x90, 0xfe, 0x54, 0x3d, 0xda, 0xf1, + 0xea, 0x85, 0x2a, 0x09, 0xfe, 0xc6, 0x3e, 0x57, 0x39, 0xdd, 0x2a, 0x8b, 0xcb, 0xbc, 0x6d, 0xae, + 0x18, 0x2f, 0x3f, 0x8f, 0xae, 0xb8, 0xbe, 0x71, 0x55, 0x5e, 0x3d, 0x25, 0x8e, 0xb5, 0x0d, 0xe1, + 0x68, 0x4b, 0x43, 0xa2, 0x5f, 0x25, 0x3d, 0x78, 0xb2, 0x9d, 0x2b, 0xaf, 0xff, 0x1f, 0x6d, 0x65, + 0x65, 0x4b, 0xe7, 0xae, 0x59, 0x79, 0xba, 0xef, 0xd7, 0xac, 0x7c, 0x62, 0x00, 0xbc, 0xfb, 0xed, + 0x9f, 0xae, 0x46, 0xbe, 0x1c, 0xcf, 0x6f, 0x2f, 0x07, 0xe1, 0xf4, 0x6a, 0xe2, 0x8f, 0xc6, 0x32, + 0xf0, 0x83, 0x51, 0xc0, 0xe5, 0x5f, 0xc2, 0xe8, 0xfe, 0x6a, 0x12, 0x0c, 0xaf, 0xf4, 0x32, 0x79, + 0xb5, 0x54, 0x77, 0xbb, 0xa7, 0xff, 0xad, 0xfa, 0xdd, 0xff, 0x02, 0x00, 0x00, 0xff, 0xff, 0x9a, + 0xf3, 0x15, 0x70, 0x86, 0x0d, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -1177,11 +1262,13 @@ const _ = grpc.SupportPackageIsVersion4 type RouterClient interface { //* //SendPayment attempts to route a payment described by the passed - //PaymentRequest to the final destination. If we are unable to route the - //payment, or cannot find a route that satisfies the constraints in the - //PaymentRequest, then an error will be returned. Otherwise, the payment - //pre-image, along with the final route will be returned. - SendPayment(ctx context.Context, in *PaymentRequest, opts ...grpc.CallOption) (*PaymentResponse, error) + //PaymentRequest to the final destination. The call returns a stream of + //payment status updates. + SendPayment(ctx context.Context, in *SendPaymentRequest, opts ...grpc.CallOption) (Router_SendPaymentClient, error) + //* + //TrackPayment returns an update stream for the payment identified by the + //payment hash. + TrackPayment(ctx context.Context, in *TrackPaymentRequest, opts ...grpc.CallOption) (Router_TrackPaymentClient, error) //* //EstimateRouteFee allows callers to obtain a lower bound w.r.t how much it //may cost to send an HTLC to the target end destination. @@ -1209,13 +1296,68 @@ func NewRouterClient(cc *grpc.ClientConn) RouterClient { return &routerClient{cc} } -func (c *routerClient) SendPayment(ctx context.Context, in *PaymentRequest, opts ...grpc.CallOption) (*PaymentResponse, error) { - out := new(PaymentResponse) - err := c.cc.Invoke(ctx, "/routerrpc.Router/SendPayment", in, out, opts...) +func (c *routerClient) SendPayment(ctx context.Context, in *SendPaymentRequest, opts ...grpc.CallOption) (Router_SendPaymentClient, error) { + stream, err := c.cc.NewStream(ctx, &_Router_serviceDesc.Streams[0], "/routerrpc.Router/SendPayment", opts...) if err != nil { return nil, err } - return out, nil + x := &routerSendPaymentClient{stream} + if err := x.ClientStream.SendMsg(in); err != nil { + return nil, err + } + if err := x.ClientStream.CloseSend(); err != nil { + return nil, err + } + return x, nil +} + +type Router_SendPaymentClient interface { + Recv() (*PaymentStatus, error) + grpc.ClientStream +} + +type routerSendPaymentClient struct { + grpc.ClientStream +} + +func (x *routerSendPaymentClient) Recv() (*PaymentStatus, error) { + m := new(PaymentStatus) + if err := x.ClientStream.RecvMsg(m); err != nil { + return nil, err + } + return m, nil +} + +func (c *routerClient) TrackPayment(ctx context.Context, in *TrackPaymentRequest, opts ...grpc.CallOption) (Router_TrackPaymentClient, error) { + stream, err := c.cc.NewStream(ctx, &_Router_serviceDesc.Streams[1], "/routerrpc.Router/TrackPayment", opts...) + if err != nil { + return nil, err + } + x := &routerTrackPaymentClient{stream} + if err := x.ClientStream.SendMsg(in); err != nil { + return nil, err + } + if err := x.ClientStream.CloseSend(); err != nil { + return nil, err + } + return x, nil +} + +type Router_TrackPaymentClient interface { + Recv() (*PaymentStatus, error) + grpc.ClientStream +} + +type routerTrackPaymentClient struct { + grpc.ClientStream +} + +func (x *routerTrackPaymentClient) Recv() (*PaymentStatus, error) { + m := new(PaymentStatus) + if err := x.ClientStream.RecvMsg(m); err != nil { + return nil, err + } + return m, nil } func (c *routerClient) EstimateRouteFee(ctx context.Context, in *RouteFeeRequest, opts ...grpc.CallOption) (*RouteFeeResponse, error) { @@ -1258,11 +1400,13 @@ func (c *routerClient) QueryMissionControl(ctx context.Context, in *QueryMission type RouterServer interface { //* //SendPayment attempts to route a payment described by the passed - //PaymentRequest to the final destination. If we are unable to route the - //payment, or cannot find a route that satisfies the constraints in the - //PaymentRequest, then an error will be returned. Otherwise, the payment - //pre-image, along with the final route will be returned. - SendPayment(context.Context, *PaymentRequest) (*PaymentResponse, error) + //PaymentRequest to the final destination. The call returns a stream of + //payment status updates. + SendPayment(*SendPaymentRequest, Router_SendPaymentServer) error + //* + //TrackPayment returns an update stream for the payment identified by the + //payment hash. + TrackPayment(*TrackPaymentRequest, Router_TrackPaymentServer) error //* //EstimateRouteFee allows callers to obtain a lower bound w.r.t how much it //may cost to send an HTLC to the target end destination. @@ -1286,22 +1430,46 @@ func RegisterRouterServer(s *grpc.Server, srv RouterServer) { s.RegisterService(&_Router_serviceDesc, srv) } -func _Router_SendPayment_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(PaymentRequest) - if err := dec(in); err != nil { - return nil, err +func _Router_SendPayment_Handler(srv interface{}, stream grpc.ServerStream) error { + m := new(SendPaymentRequest) + if err := stream.RecvMsg(m); err != nil { + return err } - if interceptor == nil { - return srv.(RouterServer).SendPayment(ctx, in) + return srv.(RouterServer).SendPayment(m, &routerSendPaymentServer{stream}) +} + +type Router_SendPaymentServer interface { + Send(*PaymentStatus) error + grpc.ServerStream +} + +type routerSendPaymentServer struct { + grpc.ServerStream +} + +func (x *routerSendPaymentServer) Send(m *PaymentStatus) error { + return x.ServerStream.SendMsg(m) +} + +func _Router_TrackPayment_Handler(srv interface{}, stream grpc.ServerStream) error { + m := new(TrackPaymentRequest) + if err := stream.RecvMsg(m); err != nil { + return err } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: "/routerrpc.Router/SendPayment", - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(RouterServer).SendPayment(ctx, req.(*PaymentRequest)) - } - return interceptor(ctx, in, info, handler) + return srv.(RouterServer).TrackPayment(m, &routerTrackPaymentServer{stream}) +} + +type Router_TrackPaymentServer interface { + Send(*PaymentStatus) error + grpc.ServerStream +} + +type routerTrackPaymentServer struct { + grpc.ServerStream +} + +func (x *routerTrackPaymentServer) Send(m *PaymentStatus) error { + return x.ServerStream.SendMsg(m) } func _Router_EstimateRouteFee_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { @@ -1380,10 +1548,6 @@ var _Router_serviceDesc = grpc.ServiceDesc{ ServiceName: "routerrpc.Router", HandlerType: (*RouterServer)(nil), Methods: []grpc.MethodDesc{ - { - MethodName: "SendPayment", - Handler: _Router_SendPayment_Handler, - }, { MethodName: "EstimateRouteFee", Handler: _Router_EstimateRouteFee_Handler, @@ -1401,6 +1565,17 @@ var _Router_serviceDesc = grpc.ServiceDesc{ Handler: _Router_QueryMissionControl_Handler, }, }, - Streams: []grpc.StreamDesc{}, + Streams: []grpc.StreamDesc{ + { + StreamName: "SendPayment", + Handler: _Router_SendPayment_Handler, + ServerStreams: true, + }, + { + StreamName: "TrackPayment", + Handler: _Router_TrackPayment_Handler, + ServerStreams: true, + }, + }, Metadata: "routerrpc/router.proto", } diff --git a/lnrpc/routerrpc/router.proto b/lnrpc/routerrpc/router.proto index f80f54c3..8646bd03 100644 --- a/lnrpc/routerrpc/router.proto +++ b/lnrpc/routerrpc/router.proto @@ -6,7 +6,7 @@ package routerrpc; option go_package = "github.com/lightningnetwork/lnd/lnrpc/routerrpc"; -message PaymentRequest { +message SendPaymentRequest { /// The identity pubkey of the payment recipient bytes dest = 1; @@ -60,24 +60,51 @@ message PaymentRequest { int32 cltv_limit = 9; } -message PaymentResponse { - /** - The payment hash that we paid to. Provided so callers are able to map - responses (which may be streaming) back to their original requests. - */ - bytes pay_hash = 1; - - /** - The pre-image of the payment successfully completed. - */ - bytes pre_image = 2; - - /** - If not an empty string, then a string representation of the payment error. - */ - string payment_err = 3; +message TrackPaymentRequest { + /// The hash of the payment to look up. + bytes payment_hash = 1; } +enum PaymentState { + /** + Payment is still in flight. + */ + IN_FLIGHT = 0; + + /** + Payment completed successfully. + */ + SUCCEEDED = 1; + + /** + There are more routes to try, but the payment timeout was exceeded. + */ + FAILED_TIMEOUT = 2; + + /** + All possible routes were tried and failed permanently. Or were no + routes to the destination at all. + */ + FAILED_NO_ROUTE = 3; +} + + +message PaymentStatus { + /// Current state the payment is in. + PaymentState state = 1; + + /** + The pre-image of the payment when state is SUCCEEDED. + */ + bytes preimage = 2; + + /** + The taken route when state is SUCCEEDED. + */ + lnrpc.Route route = 3; +} + + message RouteFeeRequest { /** The destination once wishes to obtain a routing fee quote to. @@ -305,12 +332,17 @@ message ChannelHistory { service Router { /** SendPayment attempts to route a payment described by the passed - PaymentRequest to the final destination. If we are unable to route the - payment, or cannot find a route that satisfies the constraints in the - PaymentRequest, then an error will be returned. Otherwise, the payment - pre-image, along with the final route will be returned. + PaymentRequest to the final destination. The call returns a stream of + payment status updates. */ - rpc SendPayment(PaymentRequest) returns (PaymentResponse); + rpc SendPayment(SendPaymentRequest) returns (stream PaymentStatus); + + /** + TrackPayment returns an update stream for the payment identified by the + payment hash. + */ + rpc TrackPayment(TrackPaymentRequest) returns (stream PaymentStatus); + /** EstimateRouteFee allows callers to obtain a lower bound w.r.t how much it diff --git a/lnrpc/routerrpc/router_backend.go b/lnrpc/routerrpc/router_backend.go index f1eb61f4..af102006 100644 --- a/lnrpc/routerrpc/router_backend.go +++ b/lnrpc/routerrpc/router_backend.go @@ -47,6 +47,10 @@ type RouterBackend struct { // that we receive payment requests that send to destinations on our // network. ActiveNetParams *chaincfg.Params + + // Tower is the ControlTower instance that is used to track pending + // payments. + Tower routing.ControlTower } // QueryRoutes attempts to query the daemons' Channel Router for a possible @@ -349,8 +353,8 @@ func (r *RouterBackend) UnmarshallRoute(rpcroute *lnrpc.Route) ( // extractIntentFromSendRequest attempts to parse the SendRequest details // required to dispatch a client from the information presented by an RPC // client. -func (r *RouterBackend) extractIntentFromSendRequest(rpcPayReq *PaymentRequest) ( - *routing.LightningPayment, error) { +func (r *RouterBackend) extractIntentFromSendRequest( + rpcPayReq *SendPaymentRequest) (*routing.LightningPayment, error) { payIntent := &routing.LightningPayment{} diff --git a/lnrpc/routerrpc/router_server.go b/lnrpc/routerrpc/router_server.go index 5047fc4e..58e9d2ee 100644 --- a/lnrpc/routerrpc/router_server.go +++ b/lnrpc/routerrpc/router_server.go @@ -10,15 +10,18 @@ import ( "os" "path/filepath" - "github.com/lightningnetwork/lnd/htlcswitch" - "github.com/lightningnetwork/lnd/lntypes" - "github.com/btcsuite/btcutil" + "github.com/lightningnetwork/lnd/channeldb" + "github.com/lightningnetwork/lnd/htlcswitch" "github.com/lightningnetwork/lnd/lnrpc" + "github.com/lightningnetwork/lnd/lntypes" "github.com/lightningnetwork/lnd/lnwire" "github.com/lightningnetwork/lnd/routing" "github.com/lightningnetwork/lnd/routing/route" + "google.golang.org/grpc" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" "gopkg.in/macaroon-bakery.v2/bakery" ) @@ -53,6 +56,10 @@ var ( Entity: "offchain", Action: "write", }}, + "/routerrpc.Router/TrackPayment": {{ + Entity: "offchain", + Action: "read", + }}, "/routerrpc.Router/EstimateRouteFee": {{ Entity: "offchain", Action: "read", @@ -185,23 +192,35 @@ func (s *Server) RegisterWithRootServer(grpcServer *grpc.Server) error { // payment, or cannot find a route that satisfies the constraints in the // PaymentRequest, then an error will be returned. Otherwise, the payment // pre-image, along with the final route will be returned. -func (s *Server) SendPayment(ctx context.Context, - req *PaymentRequest) (*PaymentResponse, error) { +func (s *Server) SendPayment(req *SendPaymentRequest, + stream Router_SendPaymentServer) error { payment, err := s.cfg.RouterBackend.extractIntentFromSendRequest(req) if err != nil { - return nil, err + return err } - preImage, _, err := s.cfg.Router.SendPayment(payment) + err = s.cfg.Router.SendPaymentAsync(payment) if err != nil { - return nil, err + // Transform user errors to grpc code. + if err == channeldb.ErrPaymentInFlight || + err == channeldb.ErrAlreadyPaid { + + log.Debugf("SendPayment async result for hash %x: %v", + payment.PaymentHash, err) + + return status.Error( + codes.AlreadyExists, err.Error(), + ) + } + + log.Errorf("SendPayment async error for hash %x: %v", + payment.PaymentHash, err) + + return err } - return &PaymentResponse{ - PayHash: payment.PaymentHash[:], - PreImage: preImage[:], - }, nil + return s.trackPayment(payment.PaymentHash, stream) } // EstimateRouteFee allows callers to obtain a lower bound w.r.t how much it @@ -460,3 +479,89 @@ func (s *Server) QueryMissionControl(ctx context.Context, return &response, nil } + +// TrackPayment returns a stream of payment state updates. The stream is +// closed when the payment completes. +func (s *Server) TrackPayment(request *TrackPaymentRequest, + stream Router_TrackPaymentServer) error { + + paymentHash, err := lntypes.MakeHash(request.PaymentHash) + if err != nil { + return err + } + + log.Debugf("TrackPayment called for payment %v", paymentHash) + + return s.trackPayment(paymentHash, stream) +} + +// trackPayment writes payment status updates to the provided stream. +func (s *Server) trackPayment(paymentHash lntypes.Hash, + stream Router_TrackPaymentServer) error { + + // Subscribe to the outcome of this payment. + inFlight, resultChan, err := s.cfg.RouterBackend.Tower.SubscribePayment( + paymentHash, + ) + switch { + case err == channeldb.ErrPaymentNotInitiated: + return status.Error(codes.NotFound, err.Error()) + case err != nil: + return err + } + + // If it is in flight, send a state update to the client. Payment status + // update streams are expected to always send the current payment state + // immediately. + if inFlight { + err = stream.Send(&PaymentStatus{ + State: PaymentState_IN_FLIGHT, + }) + if err != nil { + return err + } + } + + // Wait for the outcome of the payment. For payments that have + // completed, the result should already be waiting on the channel. + select { + case result := <-resultChan: + // Marshall result to rpc type. + var status PaymentStatus + + if result.Success { + log.Debugf("Payment %v successfully completed", + paymentHash) + + status.State = PaymentState_SUCCEEDED + status.Preimage = result.Preimage[:] + status.Route = s.cfg.RouterBackend.MarshallRoute( + result.Route, + ) + } else { + switch result.FailureReason { + + case channeldb.FailureReasonTimeout: + status.State = PaymentState_FAILED_TIMEOUT + + case channeldb.FailureReasonNoRoute: + status.State = PaymentState_FAILED_NO_ROUTE + + default: + return errors.New("unknown failure reason") + } + } + + // Send event to the client. + err = stream.Send(&status) + if err != nil { + return err + } + + case <-stream.Context().Done(): + log.Debugf("Payment status stream %v canceled", paymentHash) + return stream.Context().Err() + } + + return nil +} diff --git a/rpcserver.go b/rpcserver.go index d5fb47d6..b827b65b 100644 --- a/rpcserver.go +++ b/rpcserver.go @@ -477,6 +477,7 @@ func newRPCServer(s *server, macService *macaroons.Service, FindRoute: s.chanRouter.FindRoute, MissionControl: s.missionControl, ActiveNetParams: activeNetParams.Params, + Tower: s.controlTower, } var ( diff --git a/server.go b/server.go index 6e85dc3d..7887a8f2 100644 --- a/server.go +++ b/server.go @@ -192,6 +192,8 @@ type server struct { chanRouter *routing.ChannelRouter + controlTower routing.ControlTower + authGossiper *discovery.AuthenticatedGossiper utxoNursery *utxoNursery @@ -651,12 +653,14 @@ func newServer(listenAddrs []net.Addr, chanDB *channeldb.DB, cc *chainControl, paymentControl := channeldb.NewPaymentControl(chanDB) + s.controlTower = routing.NewControlTower(paymentControl) + s.chanRouter, err = routing.New(routing.Config{ Graph: chanGraph, Chain: cc.chainIO, ChainView: cc.chainView, Payer: s.htlcSwitch, - Control: routing.NewControlTower(paymentControl), + Control: s.controlTower, MissionControl: s.missionControl, ChannelPruneExpiry: routing.DefaultChannelPruneExpiry, GraphPruneInterval: time.Duration(time.Hour),