From 64dad77e2e2b366ebd159e403acb780731f36d9d Mon Sep 17 00:00:00 2001 From: carla Date: Tue, 19 Jan 2021 10:57:15 +0200 Subject: [PATCH] multi: add get and set mission control to routerrpc --- lnrpc/rest-annotations.yaml | 5 + lnrpc/routerrpc/router.pb.go | 701 ++++++++++++++++++------- lnrpc/routerrpc/router.pb.gw.go | 62 +++ lnrpc/routerrpc/router.proto | 74 +++ lnrpc/routerrpc/router.swagger.json | 65 +++ lnrpc/routerrpc/router_backend.go | 7 + lnrpc/routerrpc/router_backend_test.go | 1 + lnrpc/routerrpc/router_server.go | 48 ++ lntest/itest/lnd_test.go | 49 ++ routing/mock_test.go | 1 + 10 files changed, 832 insertions(+), 181 deletions(-) diff --git a/lnrpc/rest-annotations.yaml b/lnrpc/rest-annotations.yaml index fae8d577..927dd63e 100644 --- a/lnrpc/rest-annotations.yaml +++ b/lnrpc/rest-annotations.yaml @@ -208,6 +208,11 @@ http: body: "*" - selector: routerrpc.Router.QueryMissionControl get: "/v2/router/mc" + - selector: routerrpc.Router.GetMissionControlConfig + get: "/v2/router/mccfg" + - selector: routerroc.Router.SetMissionControlConfig + post: "/v2/router/mccfg" + body: "*" - selector: routerrpc.Router.QueryProbability get: "/v2/router/mc/probability/{from_node}/{to_node}/{amt_msat}" - selector: routerrpc.Router.BuildRoute diff --git a/lnrpc/routerrpc/router.pb.go b/lnrpc/routerrpc/router.pb.go index 7d454125..5d552c19 100644 --- a/lnrpc/routerrpc/router.pb.go +++ b/lnrpc/routerrpc/router.pb.go @@ -225,7 +225,7 @@ func (x HtlcEvent_EventType) String() string { } func (HtlcEvent_EventType) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_7a0613f69d37b0a5, []int{17, 0} + return fileDescriptor_7a0613f69d37b0a5, []int{22, 0} } type SendPaymentRequest struct { @@ -1029,6 +1029,245 @@ func (m *PairData) GetSuccessAmtMsat() int64 { return 0 } +type GetMissionControlConfigRequest struct { + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *GetMissionControlConfigRequest) Reset() { *m = GetMissionControlConfigRequest{} } +func (m *GetMissionControlConfigRequest) String() string { return proto.CompactTextString(m) } +func (*GetMissionControlConfigRequest) ProtoMessage() {} +func (*GetMissionControlConfigRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_7a0613f69d37b0a5, []int{12} +} + +func (m *GetMissionControlConfigRequest) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_GetMissionControlConfigRequest.Unmarshal(m, b) +} +func (m *GetMissionControlConfigRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_GetMissionControlConfigRequest.Marshal(b, m, deterministic) +} +func (m *GetMissionControlConfigRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_GetMissionControlConfigRequest.Merge(m, src) +} +func (m *GetMissionControlConfigRequest) XXX_Size() int { + return xxx_messageInfo_GetMissionControlConfigRequest.Size(m) +} +func (m *GetMissionControlConfigRequest) XXX_DiscardUnknown() { + xxx_messageInfo_GetMissionControlConfigRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_GetMissionControlConfigRequest proto.InternalMessageInfo + +type GetMissionControlConfigResponse struct { + // + //Mission control's currently active config. + Config *MissionControlConfig `protobuf:"bytes,1,opt,name=config,proto3" json:"config,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *GetMissionControlConfigResponse) Reset() { *m = GetMissionControlConfigResponse{} } +func (m *GetMissionControlConfigResponse) String() string { return proto.CompactTextString(m) } +func (*GetMissionControlConfigResponse) ProtoMessage() {} +func (*GetMissionControlConfigResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_7a0613f69d37b0a5, []int{13} +} + +func (m *GetMissionControlConfigResponse) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_GetMissionControlConfigResponse.Unmarshal(m, b) +} +func (m *GetMissionControlConfigResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_GetMissionControlConfigResponse.Marshal(b, m, deterministic) +} +func (m *GetMissionControlConfigResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_GetMissionControlConfigResponse.Merge(m, src) +} +func (m *GetMissionControlConfigResponse) XXX_Size() int { + return xxx_messageInfo_GetMissionControlConfigResponse.Size(m) +} +func (m *GetMissionControlConfigResponse) XXX_DiscardUnknown() { + xxx_messageInfo_GetMissionControlConfigResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_GetMissionControlConfigResponse proto.InternalMessageInfo + +func (m *GetMissionControlConfigResponse) GetConfig() *MissionControlConfig { + if m != nil { + return m.Config + } + return nil +} + +type SetMissionControlConfigRequest struct { + // + //The config to set for mission control. Note that all values *must* be set, + //because the full config will be applied. + Config *MissionControlConfig `protobuf:"bytes,1,opt,name=config,proto3" json:"config,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *SetMissionControlConfigRequest) Reset() { *m = SetMissionControlConfigRequest{} } +func (m *SetMissionControlConfigRequest) String() string { return proto.CompactTextString(m) } +func (*SetMissionControlConfigRequest) ProtoMessage() {} +func (*SetMissionControlConfigRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_7a0613f69d37b0a5, []int{14} +} + +func (m *SetMissionControlConfigRequest) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_SetMissionControlConfigRequest.Unmarshal(m, b) +} +func (m *SetMissionControlConfigRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_SetMissionControlConfigRequest.Marshal(b, m, deterministic) +} +func (m *SetMissionControlConfigRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_SetMissionControlConfigRequest.Merge(m, src) +} +func (m *SetMissionControlConfigRequest) XXX_Size() int { + return xxx_messageInfo_SetMissionControlConfigRequest.Size(m) +} +func (m *SetMissionControlConfigRequest) XXX_DiscardUnknown() { + xxx_messageInfo_SetMissionControlConfigRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_SetMissionControlConfigRequest proto.InternalMessageInfo + +func (m *SetMissionControlConfigRequest) GetConfig() *MissionControlConfig { + if m != nil { + return m.Config + } + return nil +} + +type SetMissionControlConfigResponse struct { + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *SetMissionControlConfigResponse) Reset() { *m = SetMissionControlConfigResponse{} } +func (m *SetMissionControlConfigResponse) String() string { return proto.CompactTextString(m) } +func (*SetMissionControlConfigResponse) ProtoMessage() {} +func (*SetMissionControlConfigResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_7a0613f69d37b0a5, []int{15} +} + +func (m *SetMissionControlConfigResponse) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_SetMissionControlConfigResponse.Unmarshal(m, b) +} +func (m *SetMissionControlConfigResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_SetMissionControlConfigResponse.Marshal(b, m, deterministic) +} +func (m *SetMissionControlConfigResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_SetMissionControlConfigResponse.Merge(m, src) +} +func (m *SetMissionControlConfigResponse) XXX_Size() int { + return xxx_messageInfo_SetMissionControlConfigResponse.Size(m) +} +func (m *SetMissionControlConfigResponse) XXX_DiscardUnknown() { + xxx_messageInfo_SetMissionControlConfigResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_SetMissionControlConfigResponse proto.InternalMessageInfo + +type MissionControlConfig struct { + // + //The amount of time mission control will take to restore a penalized node + //or channel back to 50% success probability, expressed as a unix timestamp + //in seconds. Setting this value to a higher value will penalize failures for + //longer, making mission control less likely to route through nodes and + //channels that we have previously recorded failures for. + HalfLifeSeconds uint64 `protobuf:"varint,1,opt,name=half_life_seconds,json=halfLifeSeconds,proto3" json:"half_life_seconds,omitempty"` + // + //The probability of success mission control should assign to hop in a route + //where it has no other information available. Higher values will make mission + //control more willing to try hops that we have no information about, lower + //values will discourage trying these hops. + HopProbability float32 `protobuf:"fixed32,2,opt,name=hop_probability,json=hopProbability,proto3" json:"hop_probability,omitempty"` + // + //The importance that mission control should place on historical results, + //expressed as a value in [0;1]. Setting this value to 1 will ignore all + //historical payments and just use the hop probability to assess the + //probability of success for each hop. A zero value ignores hop probability + //completely and relies entirely on historical results, unless none are + //available. + Weight float32 `protobuf:"fixed32,3,opt,name=weight,proto3" json:"weight,omitempty"` + // + //The maximum number of payment results that mission control will store. + MaximumPaymentResults uint32 `protobuf:"varint,4,opt,name=maximum_payment_results,json=maximumPaymentResults,proto3" json:"maximum_payment_results,omitempty"` + // + //The minimum time that must have passed since the previously recorded failure + //before we raise the failure amount. + MinimumFailureRelaxInterval uint64 `protobuf:"varint,5,opt,name=minimum_failure_relax_interval,json=minimumFailureRelaxInterval,proto3" json:"minimum_failure_relax_interval,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *MissionControlConfig) Reset() { *m = MissionControlConfig{} } +func (m *MissionControlConfig) String() string { return proto.CompactTextString(m) } +func (*MissionControlConfig) ProtoMessage() {} +func (*MissionControlConfig) Descriptor() ([]byte, []int) { + return fileDescriptor_7a0613f69d37b0a5, []int{16} +} + +func (m *MissionControlConfig) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_MissionControlConfig.Unmarshal(m, b) +} +func (m *MissionControlConfig) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_MissionControlConfig.Marshal(b, m, deterministic) +} +func (m *MissionControlConfig) XXX_Merge(src proto.Message) { + xxx_messageInfo_MissionControlConfig.Merge(m, src) +} +func (m *MissionControlConfig) XXX_Size() int { + return xxx_messageInfo_MissionControlConfig.Size(m) +} +func (m *MissionControlConfig) XXX_DiscardUnknown() { + xxx_messageInfo_MissionControlConfig.DiscardUnknown(m) +} + +var xxx_messageInfo_MissionControlConfig proto.InternalMessageInfo + +func (m *MissionControlConfig) GetHalfLifeSeconds() uint64 { + if m != nil { + return m.HalfLifeSeconds + } + return 0 +} + +func (m *MissionControlConfig) GetHopProbability() float32 { + if m != nil { + return m.HopProbability + } + return 0 +} + +func (m *MissionControlConfig) GetWeight() float32 { + if m != nil { + return m.Weight + } + return 0 +} + +func (m *MissionControlConfig) GetMaximumPaymentResults() uint32 { + if m != nil { + return m.MaximumPaymentResults + } + return 0 +} + +func (m *MissionControlConfig) GetMinimumFailureRelaxInterval() uint64 { + if m != nil { + return m.MinimumFailureRelaxInterval + } + return 0 +} + type QueryProbabilityRequest struct { // The source node pubkey of the pair. FromNode []byte `protobuf:"bytes,1,opt,name=from_node,json=fromNode,proto3" json:"from_node,omitempty"` @@ -1045,7 +1284,7 @@ func (m *QueryProbabilityRequest) Reset() { *m = QueryProbabilityRequest func (m *QueryProbabilityRequest) String() string { return proto.CompactTextString(m) } func (*QueryProbabilityRequest) ProtoMessage() {} func (*QueryProbabilityRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_7a0613f69d37b0a5, []int{12} + return fileDescriptor_7a0613f69d37b0a5, []int{17} } func (m *QueryProbabilityRequest) XXX_Unmarshal(b []byte) error { @@ -1101,7 +1340,7 @@ func (m *QueryProbabilityResponse) Reset() { *m = QueryProbabilityRespon func (m *QueryProbabilityResponse) String() string { return proto.CompactTextString(m) } func (*QueryProbabilityResponse) ProtoMessage() {} func (*QueryProbabilityResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_7a0613f69d37b0a5, []int{13} + return fileDescriptor_7a0613f69d37b0a5, []int{18} } func (m *QueryProbabilityResponse) XXX_Unmarshal(b []byte) error { @@ -1164,7 +1403,7 @@ func (m *BuildRouteRequest) Reset() { *m = BuildRouteRequest{} } func (m *BuildRouteRequest) String() string { return proto.CompactTextString(m) } func (*BuildRouteRequest) ProtoMessage() {} func (*BuildRouteRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_7a0613f69d37b0a5, []int{14} + return fileDescriptor_7a0613f69d37b0a5, []int{19} } func (m *BuildRouteRequest) XXX_Unmarshal(b []byte) error { @@ -1233,7 +1472,7 @@ func (m *BuildRouteResponse) Reset() { *m = BuildRouteResponse{} } func (m *BuildRouteResponse) String() string { return proto.CompactTextString(m) } func (*BuildRouteResponse) ProtoMessage() {} func (*BuildRouteResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_7a0613f69d37b0a5, []int{15} + return fileDescriptor_7a0613f69d37b0a5, []int{20} } func (m *BuildRouteResponse) XXX_Unmarshal(b []byte) error { @@ -1271,7 +1510,7 @@ func (m *SubscribeHtlcEventsRequest) Reset() { *m = SubscribeHtlcEventsR func (m *SubscribeHtlcEventsRequest) String() string { return proto.CompactTextString(m) } func (*SubscribeHtlcEventsRequest) ProtoMessage() {} func (*SubscribeHtlcEventsRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_7a0613f69d37b0a5, []int{16} + return fileDescriptor_7a0613f69d37b0a5, []int{21} } func (m *SubscribeHtlcEventsRequest) XXX_Unmarshal(b []byte) error { @@ -1338,7 +1577,7 @@ func (m *HtlcEvent) Reset() { *m = HtlcEvent{} } func (m *HtlcEvent) String() string { return proto.CompactTextString(m) } func (*HtlcEvent) ProtoMessage() {} func (*HtlcEvent) Descriptor() ([]byte, []int) { - return fileDescriptor_7a0613f69d37b0a5, []int{17} + return fileDescriptor_7a0613f69d37b0a5, []int{22} } func (m *HtlcEvent) XXX_Unmarshal(b []byte) error { @@ -1492,7 +1731,7 @@ func (m *HtlcInfo) Reset() { *m = HtlcInfo{} } func (m *HtlcInfo) String() string { return proto.CompactTextString(m) } func (*HtlcInfo) ProtoMessage() {} func (*HtlcInfo) Descriptor() ([]byte, []int) { - return fileDescriptor_7a0613f69d37b0a5, []int{18} + return fileDescriptor_7a0613f69d37b0a5, []int{23} } func (m *HtlcInfo) XXX_Unmarshal(b []byte) error { @@ -1553,7 +1792,7 @@ func (m *ForwardEvent) Reset() { *m = ForwardEvent{} } func (m *ForwardEvent) String() string { return proto.CompactTextString(m) } func (*ForwardEvent) ProtoMessage() {} func (*ForwardEvent) Descriptor() ([]byte, []int) { - return fileDescriptor_7a0613f69d37b0a5, []int{19} + return fileDescriptor_7a0613f69d37b0a5, []int{24} } func (m *ForwardEvent) XXX_Unmarshal(b []byte) error { @@ -1591,7 +1830,7 @@ func (m *ForwardFailEvent) Reset() { *m = ForwardFailEvent{} } func (m *ForwardFailEvent) String() string { return proto.CompactTextString(m) } func (*ForwardFailEvent) ProtoMessage() {} func (*ForwardFailEvent) Descriptor() ([]byte, []int) { - return fileDescriptor_7a0613f69d37b0a5, []int{20} + return fileDescriptor_7a0613f69d37b0a5, []int{25} } func (m *ForwardFailEvent) XXX_Unmarshal(b []byte) error { @@ -1622,7 +1861,7 @@ func (m *SettleEvent) Reset() { *m = SettleEvent{} } func (m *SettleEvent) String() string { return proto.CompactTextString(m) } func (*SettleEvent) ProtoMessage() {} func (*SettleEvent) Descriptor() ([]byte, []int) { - return fileDescriptor_7a0613f69d37b0a5, []int{21} + return fileDescriptor_7a0613f69d37b0a5, []int{26} } func (m *SettleEvent) XXX_Unmarshal(b []byte) error { @@ -1664,7 +1903,7 @@ func (m *LinkFailEvent) Reset() { *m = LinkFailEvent{} } func (m *LinkFailEvent) String() string { return proto.CompactTextString(m) } func (*LinkFailEvent) ProtoMessage() {} func (*LinkFailEvent) Descriptor() ([]byte, []int) { - return fileDescriptor_7a0613f69d37b0a5, []int{22} + return fileDescriptor_7a0613f69d37b0a5, []int{27} } func (m *LinkFailEvent) XXX_Unmarshal(b []byte) error { @@ -1731,7 +1970,7 @@ 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{23} + return fileDescriptor_7a0613f69d37b0a5, []int{28} } func (m *PaymentStatus) XXX_Unmarshal(b []byte) error { @@ -1787,7 +2026,7 @@ func (m *CircuitKey) Reset() { *m = CircuitKey{} } func (m *CircuitKey) String() string { return proto.CompactTextString(m) } func (*CircuitKey) ProtoMessage() {} func (*CircuitKey) Descriptor() ([]byte, []int) { - return fileDescriptor_7a0613f69d37b0a5, []int{24} + return fileDescriptor_7a0613f69d37b0a5, []int{29} } func (m *CircuitKey) XXX_Unmarshal(b []byte) error { @@ -1857,7 +2096,7 @@ func (m *ForwardHtlcInterceptRequest) Reset() { *m = ForwardHtlcIntercep func (m *ForwardHtlcInterceptRequest) String() string { return proto.CompactTextString(m) } func (*ForwardHtlcInterceptRequest) ProtoMessage() {} func (*ForwardHtlcInterceptRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_7a0613f69d37b0a5, []int{25} + return fileDescriptor_7a0613f69d37b0a5, []int{30} } func (m *ForwardHtlcInterceptRequest) XXX_Unmarshal(b []byte) error { @@ -1965,7 +2204,7 @@ func (m *ForwardHtlcInterceptResponse) Reset() { *m = ForwardHtlcInterce func (m *ForwardHtlcInterceptResponse) String() string { return proto.CompactTextString(m) } func (*ForwardHtlcInterceptResponse) ProtoMessage() {} func (*ForwardHtlcInterceptResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_7a0613f69d37b0a5, []int{26} + return fileDescriptor_7a0613f69d37b0a5, []int{31} } func (m *ForwardHtlcInterceptResponse) XXX_Unmarshal(b []byte) error { @@ -2025,6 +2264,11 @@ func init() { proto.RegisterType((*QueryMissionControlResponse)(nil), "routerrpc.QueryMissionControlResponse") proto.RegisterType((*PairHistory)(nil), "routerrpc.PairHistory") proto.RegisterType((*PairData)(nil), "routerrpc.PairData") + proto.RegisterType((*GetMissionControlConfigRequest)(nil), "routerrpc.GetMissionControlConfigRequest") + proto.RegisterType((*GetMissionControlConfigResponse)(nil), "routerrpc.GetMissionControlConfigResponse") + proto.RegisterType((*SetMissionControlConfigRequest)(nil), "routerrpc.SetMissionControlConfigRequest") + proto.RegisterType((*SetMissionControlConfigResponse)(nil), "routerrpc.SetMissionControlConfigResponse") + proto.RegisterType((*MissionControlConfig)(nil), "routerrpc.MissionControlConfig") proto.RegisterType((*QueryProbabilityRequest)(nil), "routerrpc.QueryProbabilityRequest") proto.RegisterType((*QueryProbabilityResponse)(nil), "routerrpc.QueryProbabilityResponse") proto.RegisterType((*BuildRouteRequest)(nil), "routerrpc.BuildRouteRequest") @@ -2046,171 +2290,184 @@ func init() { func init() { proto.RegisterFile("routerrpc/router.proto", fileDescriptor_7a0613f69d37b0a5) } var fileDescriptor_7a0613f69d37b0a5 = []byte{ - // 2622 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x59, 0xcd, 0x76, 0xdb, 0xc6, - 0xf5, 0x0f, 0xf8, 0x25, 0xf2, 0xf2, 0x43, 0xd0, 0x48, 0xb1, 0xf8, 0xa7, 0xec, 0x84, 0x61, 0x12, - 0x9b, 0xc7, 0xff, 0x44, 0x56, 0xd4, 0x9e, 0x36, 0x6d, 0x3e, 0x1a, 0x8a, 0x84, 0x2c, 0xd8, 0x14, - 0xa9, 0x0c, 0x29, 0x27, 0x69, 0x16, 0x53, 0x88, 0x18, 0x8a, 0xa8, 0x40, 0x80, 0x05, 0x86, 0x76, - 0xb4, 0xec, 0xae, 0xa7, 0x0f, 0xd0, 0xc7, 0xe8, 0x13, 0xf4, 0x9c, 0x76, 0xd1, 0x55, 0x5f, 0xa2, - 0xdb, 0x3e, 0x41, 0xd7, 0x3d, 0xf3, 0x01, 0x10, 0x90, 0x28, 0xbb, 0x3d, 0xed, 0xc6, 0x26, 0x7e, - 0xf7, 0xce, 0x9d, 0x7b, 0xe7, 0x7e, 0xce, 0x08, 0xee, 0x05, 0xfe, 0x92, 0xd1, 0x20, 0x58, 0x4c, - 0x9e, 0xc8, 0x5f, 0xfb, 0x8b, 0xc0, 0x67, 0x3e, 0x2a, 0xc5, 0x78, 0xa3, 0x14, 0x2c, 0x26, 0x12, - 0x6d, 0xfd, 0x61, 0x03, 0xd0, 0x88, 0x7a, 0xf6, 0x99, 0x75, 0x3d, 0xa7, 0x1e, 0xc3, 0xf4, 0x37, - 0x4b, 0x1a, 0x32, 0x84, 0x20, 0x67, 0xd3, 0x90, 0xd5, 0xb5, 0xa6, 0xd6, 0xae, 0x60, 0xf1, 0x1b, - 0xe9, 0x90, 0xb5, 0xe6, 0xac, 0x9e, 0x69, 0x6a, 0xed, 0x2c, 0xe6, 0x3f, 0xd1, 0xff, 0x41, 0xd1, - 0x9a, 0x33, 0x32, 0x0f, 0x2d, 0x56, 0xaf, 0x08, 0x78, 0xc3, 0x9a, 0xb3, 0xd3, 0xd0, 0x62, 0xe8, - 0x3d, 0xa8, 0x2c, 0xa4, 0x48, 0x32, 0xb3, 0xc2, 0x59, 0x3d, 0x2b, 0x04, 0x95, 0x15, 0x76, 0x62, - 0x85, 0x33, 0xd4, 0x06, 0x7d, 0xea, 0x78, 0x96, 0x4b, 0x26, 0x2e, 0x7b, 0x49, 0x6c, 0xea, 0x32, - 0xab, 0x9e, 0x6b, 0x6a, 0xed, 0x3c, 0xae, 0x09, 0xbc, 0xeb, 0xb2, 0x97, 0x3d, 0x8e, 0x26, 0x85, - 0x59, 0xb6, 0x1d, 0xd4, 0x77, 0x52, 0xc2, 0x3a, 0xb6, 0x1d, 0xa0, 0x47, 0xb0, 0x19, 0xb1, 0x04, - 0xd2, 0x86, 0x7a, 0xbe, 0xa9, 0xb5, 0x4b, 0xb8, 0xb6, 0x48, 0x5b, 0xf6, 0x08, 0x36, 0x99, 0x33, - 0xa7, 0xfe, 0x92, 0x91, 0x90, 0x4e, 0x7c, 0xcf, 0x0e, 0xeb, 0x05, 0xb9, 0xa9, 0x82, 0x47, 0x12, - 0x45, 0x2d, 0xa8, 0x4e, 0x29, 0x25, 0xae, 0x33, 0x77, 0x18, 0xe1, 0x16, 0x6e, 0x08, 0x0b, 0xcb, - 0x53, 0x4a, 0xfb, 0x1c, 0x1b, 0x59, 0x0c, 0x7d, 0x00, 0xb5, 0x15, 0x8f, 0x38, 0x86, 0xaa, 0x60, - 0xaa, 0x44, 0x4c, 0xe2, 0x2c, 0xf6, 0x41, 0xf7, 0x97, 0xec, 0xd2, 0x77, 0xbc, 0x4b, 0x32, 0x99, - 0x59, 0x1e, 0x71, 0xec, 0x7a, 0xb1, 0xa9, 0xb5, 0x73, 0x47, 0xb9, 0xba, 0x76, 0xa0, 0xe1, 0x5a, - 0x44, 0xed, 0xce, 0x2c, 0xcf, 0xb4, 0xd1, 0x63, 0xd8, 0xba, 0xc9, 0x1f, 0xd6, 0xb7, 0x9b, 0xd9, - 0x76, 0x0e, 0x6f, 0xa6, 0x59, 0x43, 0xf4, 0x10, 0x36, 0x5d, 0x2b, 0x64, 0x64, 0xe6, 0x2f, 0xc8, - 0x62, 0x79, 0x71, 0x45, 0xaf, 0xeb, 0x35, 0x71, 0x3a, 0x55, 0x0e, 0x9f, 0xf8, 0x8b, 0x33, 0x01, - 0xa2, 0x07, 0x00, 0xe2, 0x98, 0x85, 0xaa, 0xf5, 0x92, 0xb0, 0xb8, 0xc4, 0x11, 0xa1, 0x26, 0xfa, - 0x04, 0xca, 0x22, 0x3c, 0xc8, 0xcc, 0xf1, 0x58, 0x58, 0x87, 0x66, 0xb6, 0x5d, 0x3e, 0xd4, 0xf7, - 0x5d, 0x8f, 0x47, 0x0a, 0xe6, 0x94, 0x13, 0xc7, 0x63, 0x18, 0x82, 0xe8, 0x67, 0x88, 0x6c, 0xd8, - 0xe6, 0x61, 0x41, 0x26, 0xcb, 0x90, 0xf9, 0x73, 0x12, 0xd0, 0x89, 0x1f, 0xd8, 0x61, 0xbd, 0x2c, - 0x96, 0xfe, 0x78, 0x3f, 0x8e, 0xb6, 0xfd, 0xdb, 0xe1, 0xb5, 0xdf, 0xa3, 0x21, 0xeb, 0x8a, 0x75, - 0x58, 0x2e, 0x33, 0x3c, 0x16, 0x5c, 0xe3, 0x2d, 0xfb, 0x26, 0x8e, 0x3e, 0x02, 0x64, 0xb9, 0xae, - 0xff, 0x8a, 0x84, 0xd4, 0x9d, 0x12, 0xe5, 0xcb, 0xfa, 0x66, 0x53, 0x6b, 0x17, 0xb1, 0x2e, 0x28, - 0x23, 0xea, 0x4e, 0x95, 0x78, 0xf4, 0x13, 0xa8, 0x0a, 0x9d, 0xa6, 0xd4, 0x62, 0xcb, 0x80, 0x86, - 0x75, 0xbd, 0x99, 0x6d, 0xd7, 0x0e, 0xb7, 0x94, 0x21, 0xc7, 0x12, 0x3e, 0x72, 0x18, 0xae, 0x70, - 0x3e, 0xf5, 0x1d, 0xa2, 0x3d, 0x28, 0xcd, 0xad, 0x1f, 0xc8, 0xc2, 0x0a, 0x58, 0x58, 0xdf, 0x6a, - 0x6a, 0xed, 0x2a, 0x2e, 0xce, 0xad, 0x1f, 0xce, 0xf8, 0x37, 0xda, 0x87, 0x6d, 0xcf, 0x27, 0x8e, - 0x37, 0x75, 0x9d, 0xcb, 0x19, 0x23, 0xcb, 0x85, 0x6d, 0x31, 0x1a, 0xd6, 0x91, 0xd0, 0x61, 0xcb, - 0xf3, 0x4d, 0x45, 0x39, 0x97, 0x84, 0x46, 0x0f, 0xee, 0xad, 0xb7, 0x8f, 0x67, 0x10, 0x77, 0x10, - 0x4f, 0xaa, 0x1c, 0xe6, 0x3f, 0xd1, 0x0e, 0xe4, 0x5f, 0x5a, 0xee, 0x92, 0x8a, 0xac, 0xaa, 0x60, - 0xf9, 0xf1, 0xf3, 0xcc, 0xa7, 0x5a, 0x6b, 0x06, 0xdb, 0xe3, 0xc0, 0x9a, 0x5c, 0xdd, 0x48, 0xcc, - 0x9b, 0x79, 0xa5, 0xdd, 0xce, 0xab, 0x3b, 0xf4, 0xcd, 0xdc, 0xa1, 0x6f, 0xeb, 0x4b, 0xd8, 0x14, - 0x1e, 0x3e, 0xa6, 0xf4, 0x75, 0xe9, 0xbf, 0x0b, 0x3c, 0xb9, 0x45, 0x26, 0xc8, 0x12, 0x50, 0xb0, - 0xe6, 0x3c, 0x09, 0x5a, 0x36, 0xe8, 0xab, 0xf5, 0xe1, 0xc2, 0xf7, 0x42, 0xca, 0x73, 0x9b, 0x07, - 0x00, 0x8f, 0x60, 0x9e, 0x20, 0x22, 0x35, 0x34, 0xb1, 0xaa, 0xa6, 0xf0, 0x63, 0x4a, 0x45, 0x72, - 0x3c, 0x94, 0xf9, 0x48, 0x5c, 0x7f, 0x72, 0xc5, 0x8b, 0x80, 0x75, 0xad, 0xc4, 0x57, 0x39, 0xdc, - 0xf7, 0x27, 0x57, 0x3d, 0x0e, 0xb6, 0xbe, 0x97, 0x75, 0x6a, 0xec, 0x8b, 0xbd, 0xfe, 0x83, 0xe3, - 0x68, 0x41, 0x5e, 0xc4, 0xa2, 0x10, 0x5b, 0x3e, 0xac, 0x24, 0x83, 0x1a, 0x4b, 0x52, 0xeb, 0x7b, - 0xd8, 0x4e, 0x09, 0x57, 0x56, 0x34, 0xa0, 0xb8, 0x08, 0xa8, 0x33, 0xb7, 0x2e, 0xa9, 0x92, 0x1c, - 0x7f, 0xa3, 0x36, 0x6c, 0x4c, 0x2d, 0xc7, 0x5d, 0x06, 0x91, 0xe0, 0x5a, 0x14, 0x64, 0x12, 0xc5, - 0x11, 0xb9, 0x75, 0x1f, 0x1a, 0x98, 0x86, 0x94, 0x9d, 0x3a, 0x61, 0xe8, 0xf8, 0x5e, 0xd7, 0xf7, - 0x58, 0xe0, 0xbb, 0xca, 0x82, 0xd6, 0x03, 0xd8, 0x5b, 0x4b, 0x95, 0x2a, 0xf0, 0xc5, 0x5f, 0x2f, - 0x69, 0x70, 0xbd, 0x7e, 0xf1, 0xd7, 0xb0, 0xb7, 0x96, 0xaa, 0xf4, 0xff, 0x08, 0xf2, 0x0b, 0xcb, - 0x09, 0xb8, 0xef, 0x79, 0x52, 0xde, 0x4b, 0x24, 0xe5, 0x99, 0xe5, 0x04, 0x27, 0x4e, 0xc8, 0xfc, - 0xe0, 0x1a, 0x4b, 0xa6, 0x67, 0xb9, 0xa2, 0xa6, 0x67, 0x5a, 0xbf, 0xd7, 0xa0, 0x9c, 0x20, 0xf2, - 0xd4, 0xf0, 0x7c, 0x9b, 0x92, 0x69, 0xe0, 0xcf, 0xa3, 0x43, 0xe0, 0xc0, 0x71, 0xe0, 0xcf, 0x79, - 0x4c, 0x08, 0x22, 0xf3, 0x55, 0x00, 0x17, 0xf8, 0xe7, 0xd8, 0x47, 0x1f, 0xc3, 0xc6, 0x4c, 0x0a, - 0x10, 0x65, 0xb3, 0x7c, 0xb8, 0x7d, 0x63, 0xef, 0x9e, 0xc5, 0x2c, 0x1c, 0xf1, 0x3c, 0xcb, 0x15, - 0xb3, 0x7a, 0xee, 0x59, 0xae, 0x98, 0xd3, 0xf3, 0xcf, 0x72, 0xc5, 0xbc, 0x5e, 0x78, 0x96, 0x2b, - 0x16, 0xf4, 0x8d, 0xd6, 0x3f, 0x34, 0x28, 0x46, 0xdc, 0x5c, 0x13, 0x7e, 0xa4, 0x84, 0xc7, 0x85, - 0x0a, 0xa6, 0x22, 0x07, 0xc6, 0xce, 0x9c, 0xa2, 0x26, 0x54, 0x04, 0x31, 0x1d, 0xa2, 0xc0, 0xb1, - 0x8e, 0x08, 0x53, 0x51, 0xcf, 0x23, 0x0e, 0x11, 0x8f, 0x39, 0x55, 0xcf, 0x25, 0x4b, 0xd4, 0xb5, - 0xc2, 0xe5, 0x64, 0x42, 0xc3, 0x50, 0xee, 0x92, 0x97, 0x2c, 0x0a, 0x13, 0x1b, 0x3d, 0x84, 0xcd, - 0x88, 0x25, 0xda, 0xab, 0x20, 0xe3, 0x55, 0xc1, 0x6a, 0xbb, 0x36, 0xe8, 0x49, 0xbe, 0xf9, 0xaa, - 0x83, 0xd4, 0x56, 0x8c, 0x7c, 0x53, 0x69, 0x7c, 0xeb, 0xd7, 0xb0, 0x2b, 0x5c, 0x79, 0x16, 0xf8, - 0x17, 0xd6, 0x85, 0xe3, 0x3a, 0xec, 0x3a, 0x0a, 0x72, 0x6e, 0x78, 0xe0, 0xcf, 0x09, 0x3f, 0xdb, - 0xc8, 0x05, 0x1c, 0x18, 0xf8, 0x36, 0xe5, 0x2e, 0x60, 0xbe, 0x24, 0x29, 0x17, 0x30, 0x5f, 0x10, - 0x92, 0xcd, 0x39, 0x9b, 0x6a, 0xce, 0xad, 0x2b, 0xa8, 0xdf, 0xde, 0x4b, 0xc5, 0x4c, 0x13, 0xca, - 0x8b, 0x15, 0x2c, 0xb6, 0xd3, 0x70, 0x12, 0x4a, 0xfa, 0x36, 0xf3, 0x66, 0xdf, 0xb6, 0xfe, 0xa6, - 0xc1, 0xd6, 0xd1, 0xd2, 0x71, 0xed, 0x54, 0xe2, 0x26, 0xb5, 0xd3, 0xd2, 0xa3, 0xc3, 0xba, 0xb9, - 0x20, 0xb3, 0x76, 0x2e, 0xf8, 0x68, 0x4d, 0x63, 0xcd, 0x8a, 0xc6, 0x9a, 0x59, 0xd3, 0x56, 0xdf, - 0x85, 0xf2, 0xaa, 0x4b, 0x86, 0xf5, 0x5c, 0x33, 0xdb, 0xae, 0x60, 0x98, 0x45, 0x2d, 0x32, 0xbc, - 0x35, 0x66, 0xe4, 0x6f, 0x8d, 0x19, 0xad, 0x4f, 0x01, 0x25, 0x6d, 0x51, 0x67, 0x16, 0x97, 0x18, - 0xed, 0xee, 0x12, 0x73, 0x1f, 0x1a, 0xa3, 0xe5, 0x45, 0x38, 0x09, 0x9c, 0x0b, 0x7a, 0xc2, 0xdc, - 0x89, 0xf1, 0x92, 0x7a, 0x2c, 0x8c, 0x12, 0xf9, 0x9f, 0x39, 0x28, 0xc5, 0x28, 0xaf, 0xe0, 0x8e, - 0x37, 0xf1, 0xe7, 0x91, 0x5d, 0x1e, 0x75, 0xb9, 0x69, 0xb2, 0x6f, 0x6c, 0x45, 0xa4, 0xae, 0xa4, - 0x98, 0x36, 0xe7, 0x4f, 0x9d, 0x83, 0xe2, 0xcf, 0x48, 0xfe, 0xe4, 0x31, 0x48, 0xfe, 0x36, 0xe8, - 0xb1, 0xfc, 0x19, 0x73, 0x27, 0xf1, 0xb9, 0xe1, 0x5a, 0x84, 0x73, 0x65, 0x24, 0x67, 0x2c, 0x39, - 0xe2, 0xcc, 0x49, 0xce, 0x08, 0x57, 0x9c, 0xef, 0x41, 0x85, 0xa7, 0x4c, 0xc8, 0xac, 0xf9, 0x82, - 0x78, 0xa1, 0x38, 0xbc, 0x1c, 0x2e, 0xc7, 0xd8, 0x20, 0x44, 0x5f, 0x00, 0x50, 0x6e, 0x1f, 0x61, - 0xd7, 0x0b, 0x2a, 0xb2, 0xa6, 0x76, 0xf8, 0x4e, 0x22, 0x76, 0xe2, 0x03, 0xd8, 0x17, 0xff, 0x8e, - 0xaf, 0x17, 0x14, 0x97, 0x68, 0xf4, 0x13, 0x7d, 0x09, 0xd5, 0xa9, 0x1f, 0xbc, 0xb2, 0x02, 0x9b, - 0x08, 0x50, 0x55, 0x96, 0xdd, 0x84, 0x84, 0x63, 0x49, 0x17, 0xcb, 0x4f, 0xde, 0xc2, 0x95, 0x69, - 0xe2, 0x1b, 0x3d, 0x07, 0x14, 0xad, 0x17, 0x85, 0x40, 0x0a, 0x29, 0x0a, 0x21, 0x7b, 0xb7, 0x85, - 0xf0, 0x3a, 0x1e, 0x09, 0xd2, 0xa7, 0x37, 0x30, 0xf4, 0x19, 0x54, 0x42, 0xca, 0x98, 0x4b, 0x95, - 0x98, 0x92, 0x10, 0x73, 0x2f, 0x35, 0xf6, 0x70, 0x72, 0x24, 0xa1, 0x1c, 0xae, 0x3e, 0xd1, 0x11, - 0x6c, 0xba, 0x8e, 0x77, 0x95, 0x54, 0x03, 0xc4, 0xfa, 0x7a, 0x62, 0x7d, 0xdf, 0xf1, 0xae, 0x92, - 0x3a, 0x54, 0xdd, 0x24, 0xd0, 0xfa, 0x1c, 0x4a, 0xf1, 0x29, 0xa1, 0x32, 0x6c, 0x9c, 0x0f, 0x9e, - 0x0f, 0x86, 0xdf, 0x0c, 0xf4, 0xb7, 0x50, 0x11, 0x72, 0x23, 0x63, 0xd0, 0xd3, 0x35, 0x0e, 0x63, - 0xa3, 0x6b, 0x98, 0x2f, 0x0c, 0x3d, 0xc3, 0x3f, 0x8e, 0x87, 0xf8, 0x9b, 0x0e, 0xee, 0xe9, 0xd9, - 0xa3, 0x0d, 0xc8, 0x8b, 0x7d, 0x5b, 0x7f, 0xd2, 0xa0, 0x28, 0x3c, 0xe8, 0x4d, 0x7d, 0xf4, 0xff, - 0x10, 0x07, 0x97, 0xa8, 0x7f, 0xbc, 0x27, 0x8b, 0xa8, 0xab, 0xe2, 0x38, 0x60, 0xc6, 0x0a, 0xe7, - 0xcc, 0x71, 0x68, 0xc4, 0xcc, 0x19, 0xc9, 0x1c, 0x11, 0x62, 0xe6, 0xc7, 0x09, 0xc9, 0xa9, 0xaa, - 0x94, 0xc3, 0x9b, 0x11, 0x21, 0x2a, 0xc2, 0xc9, 0xf1, 0x37, 0x55, 0xac, 0x13, 0xe3, 0xaf, 0xe2, - 0x6d, 0xfd, 0x14, 0x2a, 0x49, 0x9f, 0xa3, 0x47, 0x90, 0x73, 0xbc, 0xa9, 0xaf, 0x12, 0x71, 0xfb, - 0x46, 0x70, 0x71, 0x23, 0xb1, 0x60, 0x68, 0x21, 0xd0, 0x6f, 0xfa, 0xb9, 0x55, 0x85, 0x72, 0xc2, - 0x69, 0xad, 0xbf, 0x6b, 0x50, 0x4d, 0x39, 0xe1, 0xdf, 0x96, 0x8e, 0xbe, 0x80, 0xca, 0x2b, 0x27, - 0xa0, 0x24, 0x39, 0x21, 0xd4, 0x0e, 0x1b, 0xe9, 0x09, 0x21, 0xfa, 0xbf, 0xeb, 0xdb, 0x14, 0x97, - 0x39, 0xbf, 0x02, 0xd0, 0x2f, 0xa0, 0xa6, 0x56, 0x12, 0x9b, 0x32, 0xcb, 0x71, 0xc5, 0x51, 0xd5, - 0x52, 0xe1, 0xa1, 0x78, 0x7b, 0x82, 0x8e, 0xab, 0xd3, 0xe4, 0x27, 0xfa, 0x70, 0x25, 0x20, 0x64, - 0x81, 0xe3, 0x5d, 0x8a, 0xf3, 0x2b, 0xc5, 0x6c, 0x23, 0x01, 0xf2, 0x5e, 0x5f, 0x55, 0xf3, 0xe5, - 0x88, 0x59, 0x6c, 0x19, 0xa2, 0x8f, 0x21, 0x1f, 0x32, 0x4b, 0x55, 0xb2, 0x5a, 0x2a, 0xb7, 0x12, - 0x8c, 0x14, 0x4b, 0xae, 0xd4, 0x80, 0x94, 0xb9, 0x35, 0x20, 0xe5, 0x79, 0xc5, 0x90, 0x85, 0xb6, - 0x7c, 0x88, 0x94, 0xf1, 0x27, 0xe3, 0x7e, 0xb7, 0xc3, 0x18, 0x9d, 0x2f, 0x18, 0x96, 0x0c, 0xaa, - 0x01, 0x7e, 0x09, 0xd0, 0x75, 0x82, 0xc9, 0xd2, 0x61, 0xcf, 0xe9, 0x35, 0x6f, 0x6b, 0x51, 0x45, - 0x97, 0x65, 0xaf, 0x30, 0x91, 0x55, 0x7c, 0x17, 0x36, 0xa2, 0x42, 0x24, 0xeb, 0x5b, 0x61, 0x26, - 0x0a, 0x50, 0xeb, 0xcf, 0x39, 0xd8, 0x53, 0x2e, 0x95, 0xde, 0x60, 0x34, 0x98, 0xd0, 0x45, 0x3c, - 0x39, 0x3f, 0x85, 0x9d, 0x55, 0x51, 0x95, 0x1b, 0x91, 0x68, 0x1a, 0x2f, 0x1f, 0xbe, 0x9d, 0xb0, - 0x74, 0xa5, 0x06, 0x46, 0x71, 0xb1, 0x5d, 0xa9, 0x76, 0x90, 0x10, 0x64, 0xcd, 0xfd, 0xa5, 0xa7, - 0x42, 0x54, 0x56, 0x3c, 0xb4, 0x0a, 0x67, 0x4e, 0x12, 0x11, 0xfd, 0x08, 0xe2, 0x20, 0x27, 0xf4, - 0x87, 0x85, 0x13, 0x5c, 0x8b, 0xea, 0x57, 0x5d, 0x95, 0x5b, 0x43, 0xa0, 0xb7, 0xc6, 0xd9, 0xcc, - 0xed, 0x71, 0xf6, 0x33, 0x68, 0xc4, 0xd9, 0xa1, 0x6e, 0xba, 0xd4, 0x8e, 0xbb, 0xdf, 0x86, 0xd0, - 0x61, 0x37, 0xe2, 0xc0, 0x11, 0x83, 0x6a, 0x81, 0x07, 0xb0, 0x93, 0x48, 0xad, 0x95, 0xea, 0x32, - 0x13, 0xd1, 0x2a, 0xbb, 0x92, 0xaa, 0xc7, 0x2b, 0x94, 0xea, 0x39, 0xa9, 0x7a, 0x04, 0x2b, 0xd5, - 0x7f, 0x05, 0xb5, 0x1b, 0x37, 0xc1, 0xa2, 0xf0, 0xfb, 0xcf, 0x6e, 0x57, 0xd6, 0x75, 0xee, 0xd9, - 0x5f, 0x73, 0x1d, 0xac, 0x4e, 0x52, 0x57, 0xc1, 0x07, 0x00, 0xbe, 0xe7, 0xf8, 0x1e, 0xb9, 0x70, - 0xfd, 0x0b, 0x51, 0x70, 0x2b, 0xb8, 0x24, 0x90, 0x23, 0xd7, 0xbf, 0x68, 0x7c, 0x05, 0xe8, 0xbf, - 0xbc, 0x72, 0xfd, 0x45, 0x83, 0xfb, 0xeb, 0x55, 0x54, 0x7d, 0xfe, 0x7f, 0x16, 0x42, 0x9f, 0x41, - 0xc1, 0x9a, 0x30, 0xc7, 0xf7, 0x54, 0x65, 0x78, 0x3f, 0xb1, 0x14, 0xd3, 0xd0, 0x77, 0x5f, 0xd2, - 0x13, 0xdf, 0xb5, 0x95, 0x32, 0x1d, 0xc1, 0x8a, 0xd5, 0x92, 0x54, 0xd2, 0x65, 0xd3, 0x49, 0xf7, - 0xf8, 0xb7, 0x39, 0xa8, 0xa6, 0x2a, 0x43, 0xba, 0x35, 0x54, 0xa1, 0x34, 0x18, 0x92, 0x9e, 0x31, - 0xee, 0x98, 0x7d, 0x5d, 0x43, 0x3a, 0x54, 0x86, 0x03, 0x73, 0x38, 0x20, 0x3d, 0xa3, 0x3b, 0xec, - 0xf1, 0x26, 0xf1, 0x36, 0x6c, 0xf5, 0xcd, 0xc1, 0x73, 0x32, 0x18, 0x8e, 0x89, 0xd1, 0x37, 0x9f, - 0x9a, 0x47, 0x7d, 0x43, 0xcf, 0xa2, 0x1d, 0xd0, 0x87, 0x03, 0xd2, 0x3d, 0xe9, 0x98, 0x03, 0x32, - 0x36, 0x4f, 0x8d, 0xe1, 0xf9, 0x58, 0xcf, 0x71, 0x94, 0x67, 0x33, 0x31, 0xbe, 0xed, 0x1a, 0x46, - 0x6f, 0x44, 0x4e, 0x3b, 0xdf, 0xea, 0x79, 0x54, 0x87, 0x1d, 0x73, 0x30, 0x3a, 0x3f, 0x3e, 0x36, - 0xbb, 0xa6, 0x31, 0x18, 0x93, 0xa3, 0x4e, 0xbf, 0x33, 0xe8, 0x1a, 0x7a, 0x01, 0xdd, 0x03, 0x64, - 0x0e, 0xba, 0xc3, 0xd3, 0xb3, 0xbe, 0x31, 0x36, 0x48, 0xd4, 0x8c, 0x36, 0xd0, 0x36, 0x6c, 0x0a, - 0x39, 0x9d, 0x5e, 0x8f, 0x1c, 0x77, 0xcc, 0xbe, 0xd1, 0xd3, 0x8b, 0x5c, 0x13, 0xc5, 0x31, 0x22, - 0x3d, 0x73, 0xd4, 0x39, 0xe2, 0x70, 0x89, 0xef, 0x69, 0x0e, 0x5e, 0x0c, 0xcd, 0xae, 0x41, 0xba, - 0x5c, 0x2c, 0x47, 0x81, 0x33, 0x47, 0xe8, 0xf9, 0xa0, 0x67, 0xe0, 0xb3, 0x8e, 0xd9, 0xd3, 0xcb, - 0x68, 0x0f, 0x76, 0x23, 0xd8, 0xf8, 0xf6, 0xcc, 0xc4, 0xdf, 0x91, 0xf1, 0x70, 0x48, 0x46, 0xc3, - 0xe1, 0x40, 0xaf, 0x24, 0x25, 0x71, 0x6b, 0x87, 0x67, 0xc6, 0x40, 0xaf, 0xa2, 0x5d, 0xd8, 0x3e, - 0x3d, 0x3b, 0x23, 0x11, 0x25, 0x32, 0xb6, 0xc6, 0xd9, 0x3b, 0xbd, 0x1e, 0x36, 0x46, 0x23, 0x72, - 0x6a, 0x8e, 0x4e, 0x3b, 0xe3, 0xee, 0x89, 0xbe, 0xc9, 0x4d, 0x1a, 0x19, 0x63, 0x32, 0x1e, 0x8e, - 0x3b, 0xfd, 0x15, 0xae, 0x73, 0x85, 0x56, 0x38, 0xdf, 0xb4, 0x3f, 0xfc, 0x46, 0xdf, 0xe2, 0x07, - 0xce, 0xe1, 0xe1, 0x0b, 0xa5, 0x22, 0xe2, 0xb6, 0x2b, 0xf7, 0x44, 0x7b, 0xea, 0xdb, 0x1c, 0x34, - 0x07, 0x2f, 0x3a, 0x7d, 0xb3, 0x47, 0x9e, 0x1b, 0xdf, 0x89, 0x66, 0xbe, 0xc3, 0x41, 0xa9, 0x19, - 0x39, 0xc3, 0xc3, 0xa7, 0x5c, 0x11, 0xfd, 0x6d, 0x84, 0xa0, 0xd6, 0x35, 0x71, 0xf7, 0xbc, 0xdf, - 0xc1, 0x04, 0x0f, 0xcf, 0xc7, 0x86, 0x7e, 0xef, 0xf1, 0x1f, 0x35, 0xa8, 0x24, 0x8b, 0x35, 0xf7, - 0xba, 0x39, 0x20, 0xc7, 0x7d, 0xf3, 0xe9, 0xc9, 0x58, 0x06, 0xc1, 0xe8, 0xbc, 0xcb, 0x5d, 0x66, - 0xf0, 0x21, 0x01, 0x41, 0x4d, 0x1e, 0x7a, 0x6c, 0x6c, 0x86, 0xef, 0xa5, 0xb0, 0xc1, 0x50, 0xc9, - 0xcd, 0x72, 0xe5, 0x15, 0x68, 0x60, 0x3c, 0xc4, 0x7a, 0x0e, 0x7d, 0x00, 0x4d, 0x85, 0x70, 0xbf, - 0x62, 0x6c, 0x74, 0xc7, 0xe4, 0xac, 0xf3, 0xdd, 0x29, 0x77, 0xbb, 0x0c, 0xb2, 0x91, 0x9e, 0x47, - 0xef, 0xc2, 0x5e, 0xcc, 0xb5, 0x2e, 0x2e, 0x1e, 0x7f, 0x0e, 0xf5, 0xbb, 0x82, 0x1e, 0x01, 0x14, - 0x46, 0xc6, 0x78, 0xdc, 0x37, 0xe4, 0x60, 0x73, 0x2c, 0x03, 0x17, 0xa0, 0x80, 0x8d, 0xd1, 0xf9, - 0xa9, 0xa1, 0x67, 0x0e, 0xff, 0x5a, 0x84, 0x82, 0x98, 0xb4, 0x03, 0xf4, 0x15, 0x54, 0x13, 0x8f, - 0x4d, 0x2f, 0x0e, 0xd1, 0x83, 0xd7, 0x3e, 0x43, 0x35, 0xa2, 0x2b, 0xbb, 0x82, 0x0f, 0x34, 0x74, - 0x04, 0xb5, 0xe4, 0xab, 0xcb, 0x8b, 0x43, 0x94, 0x1c, 0x50, 0xd7, 0x3c, 0xc8, 0xac, 0x91, 0xf1, - 0x1c, 0x74, 0x23, 0x64, 0xce, 0x9c, 0xf7, 0x49, 0xf5, 0x2e, 0x82, 0x1a, 0xc9, 0x04, 0x4f, 0x3f, - 0xb6, 0x34, 0xf6, 0xd6, 0xd2, 0x54, 0xc9, 0xf9, 0x9a, 0xcf, 0x24, 0xf1, 0xcb, 0xc4, 0x2d, 0x83, - 0xd2, 0xcf, 0x21, 0x8d, 0x77, 0xee, 0x22, 0xab, 0xd7, 0x84, 0xec, 0xef, 0x32, 0xdc, 0xc6, 0x6a, - 0x82, 0xb6, 0xe6, 0x94, 0x6e, 0x08, 0x5d, 0xd3, 0xb9, 0x91, 0x0d, 0xdb, 0x6b, 0x5e, 0x2d, 0xd0, - 0x87, 0xe9, 0x3a, 0x76, 0xc7, 0x9b, 0x47, 0xe3, 0xe1, 0x9b, 0xd8, 0x94, 0xf1, 0x36, 0x6c, 0xaf, - 0x79, 0xde, 0x48, 0xed, 0x72, 0xf7, 0xe3, 0x48, 0x6a, 0x97, 0xd7, 0xbd, 0x92, 0x7c, 0x0f, 0xfa, - 0xcd, 0xdb, 0x30, 0x6a, 0xdd, 0x5c, 0x7b, 0xfb, 0x5a, 0xde, 0x78, 0xff, 0xb5, 0x3c, 0x4a, 0xb8, - 0x09, 0xb0, 0xba, 0x30, 0xa2, 0xfb, 0x89, 0x25, 0xb7, 0xee, 0xc4, 0x8d, 0x07, 0x77, 0x50, 0x95, - 0xa8, 0x31, 0x6c, 0xaf, 0xb9, 0x41, 0xa6, 0x4e, 0xe3, 0xee, 0x1b, 0x66, 0x63, 0x67, 0xdd, 0x45, - 0xeb, 0x40, 0x43, 0xa7, 0x32, 0xc0, 0xa2, 0x17, 0xd4, 0x37, 0x64, 0x4c, 0x7d, 0xfd, 0x40, 0xb8, - 0x0c, 0x45, 0x68, 0x1d, 0x68, 0x68, 0x08, 0x95, 0x64, 0x96, 0xbc, 0x31, 0x7d, 0xde, 0x28, 0x70, - 0x0a, 0x9b, 0xa9, 0x66, 0xec, 0x07, 0xe8, 0xd1, 0x1b, 0x47, 0x0a, 0x79, 0x62, 0xa9, 0x08, 0x78, - 0xcd, 0xec, 0xd1, 0xd6, 0x0e, 0xb4, 0xa3, 0x4f, 0x7e, 0xf9, 0xe4, 0xd2, 0x61, 0xb3, 0xe5, 0xc5, - 0xfe, 0xc4, 0x9f, 0x3f, 0x11, 0x0f, 0xa4, 0x9e, 0xe3, 0x5d, 0x7a, 0x94, 0xbd, 0xf2, 0x83, 0xab, - 0x27, 0xae, 0x67, 0x3f, 0x11, 0x69, 0xf0, 0x24, 0x16, 0x79, 0x51, 0x10, 0x7f, 0x42, 0xf9, 0xd1, - 0xbf, 0x02, 0x00, 0x00, 0xff, 0xff, 0xbf, 0xfc, 0xb7, 0xb8, 0x72, 0x19, 0x00, 0x00, + // 2823 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x59, 0xcb, 0x7a, 0xdb, 0xc6, + 0x15, 0x0e, 0x78, 0x13, 0x79, 0x78, 0x83, 0x46, 0xb2, 0xc5, 0x52, 0xbe, 0x30, 0x4c, 0x62, 0xb3, + 0x6e, 0x22, 0x3b, 0x6a, 0xbf, 0x24, 0x6d, 0x2e, 0x0d, 0x45, 0x42, 0x16, 0x6c, 0x8a, 0x54, 0x86, + 0x94, 0x13, 0x27, 0x8b, 0x29, 0x44, 0x0e, 0x45, 0x54, 0xb8, 0xb0, 0xc0, 0xd0, 0xb6, 0x76, 0xed, + 0xae, 0x5f, 0x1f, 0xa0, 0xcf, 0xd0, 0x55, 0x9f, 0xa0, 0xdf, 0xd7, 0xae, 0xfb, 0x12, 0xdd, 0xf6, + 0x09, 0xba, 0xee, 0x37, 0x83, 0x01, 0x08, 0x48, 0x94, 0xe4, 0x5e, 0x36, 0x36, 0xf1, 0x9f, 0x7f, + 0xce, 0x9c, 0x99, 0x39, 0xb7, 0x19, 0xc1, 0x6d, 0xcf, 0x5d, 0x30, 0xea, 0x79, 0xf3, 0xf1, 0xe3, + 0xe0, 0xd7, 0xce, 0xdc, 0x73, 0x99, 0x8b, 0x0a, 0x11, 0x5e, 0x2f, 0x78, 0xf3, 0x71, 0x80, 0x36, + 0xff, 0xb8, 0x06, 0x68, 0x48, 0x9d, 0xc9, 0x91, 0x71, 0x6e, 0x53, 0x87, 0x61, 0xfa, 0x9b, 0x05, + 0xf5, 0x19, 0x42, 0x90, 0x99, 0x50, 0x9f, 0xd5, 0x94, 0x86, 0xd2, 0x2a, 0x61, 0xf1, 0x1b, 0xa9, + 0x90, 0x36, 0x6c, 0x56, 0x4b, 0x35, 0x94, 0x56, 0x1a, 0xf3, 0x9f, 0xe8, 0x47, 0x90, 0x37, 0x6c, + 0x46, 0x6c, 0xdf, 0x60, 0xb5, 0x92, 0x80, 0xd7, 0x0c, 0x9b, 0x1d, 0xfa, 0x06, 0x43, 0xef, 0x42, + 0x69, 0x1e, 0xa8, 0x24, 0x33, 0xc3, 0x9f, 0xd5, 0xd2, 0x42, 0x51, 0x51, 0x62, 0x07, 0x86, 0x3f, + 0x43, 0x2d, 0x50, 0xa7, 0xa6, 0x63, 0x58, 0x64, 0x6c, 0xb1, 0x57, 0x64, 0x42, 0x2d, 0x66, 0xd4, + 0x32, 0x0d, 0xa5, 0x95, 0xc5, 0x15, 0x81, 0x77, 0x2c, 0xf6, 0xaa, 0xcb, 0xd1, 0xb8, 0x32, 0x63, + 0x32, 0xf1, 0x6a, 0x9b, 0x09, 0x65, 0xed, 0xc9, 0xc4, 0x43, 0x0f, 0xa1, 0x1a, 0x52, 0xbc, 0x60, + 0x0d, 0xb5, 0x6c, 0x43, 0x69, 0x15, 0x70, 0x65, 0x9e, 0x5c, 0xd9, 0x43, 0xa8, 0x32, 0xd3, 0xa6, + 0xee, 0x82, 0x11, 0x9f, 0x8e, 0x5d, 0x67, 0xe2, 0xd7, 0x72, 0xc1, 0xa4, 0x12, 0x1e, 0x06, 0x28, + 0x6a, 0x42, 0x79, 0x4a, 0x29, 0xb1, 0x4c, 0xdb, 0x64, 0x84, 0xaf, 0x70, 0x4d, 0xac, 0xb0, 0x38, + 0xa5, 0xb4, 0xc7, 0xb1, 0xa1, 0xc1, 0xd0, 0xfb, 0x50, 0x59, 0x72, 0xc4, 0x36, 0x94, 0x05, 0xa9, + 0x14, 0x92, 0xc4, 0x5e, 0xec, 0x80, 0xea, 0x2e, 0xd8, 0xa9, 0x6b, 0x3a, 0xa7, 0x64, 0x3c, 0x33, + 0x1c, 0x62, 0x4e, 0x6a, 0xf9, 0x86, 0xd2, 0xca, 0xec, 0x65, 0x6a, 0xca, 0x13, 0x05, 0x57, 0x42, + 0x69, 0x67, 0x66, 0x38, 0xfa, 0x04, 0x3d, 0x82, 0xf5, 0x8b, 0x7c, 0xbf, 0xb6, 0xd1, 0x48, 0xb7, + 0x32, 0xb8, 0x9a, 0xa4, 0xfa, 0xe8, 0x01, 0x54, 0x2d, 0xc3, 0x67, 0x64, 0xe6, 0xce, 0xc9, 0x7c, + 0x71, 0x72, 0x46, 0xcf, 0x6b, 0x15, 0xb1, 0x3b, 0x65, 0x0e, 0x1f, 0xb8, 0xf3, 0x23, 0x01, 0xa2, + 0xbb, 0x00, 0x62, 0x9b, 0x85, 0xa9, 0xb5, 0x82, 0x58, 0x71, 0x81, 0x23, 0xc2, 0x4c, 0xf4, 0x31, + 0x14, 0x85, 0x7b, 0x90, 0x99, 0xe9, 0x30, 0xbf, 0x06, 0x8d, 0x74, 0xab, 0xb8, 0xab, 0xee, 0x58, + 0x0e, 0xf7, 0x14, 0xcc, 0x25, 0x07, 0xa6, 0xc3, 0x30, 0x78, 0xe1, 0x4f, 0x1f, 0x4d, 0x60, 0x83, + 0xbb, 0x05, 0x19, 0x2f, 0x7c, 0xe6, 0xda, 0xc4, 0xa3, 0x63, 0xd7, 0x9b, 0xf8, 0xb5, 0xa2, 0x18, + 0xfa, 0xb3, 0x9d, 0xc8, 0xdb, 0x76, 0x2e, 0xbb, 0xd7, 0x4e, 0x97, 0xfa, 0xac, 0x23, 0xc6, 0xe1, + 0x60, 0x98, 0xe6, 0x30, 0xef, 0x1c, 0xaf, 0x4f, 0x2e, 0xe2, 0xe8, 0x43, 0x40, 0x86, 0x65, 0xb9, + 0xaf, 0x89, 0x4f, 0xad, 0x29, 0x91, 0x67, 0x59, 0xab, 0x36, 0x94, 0x56, 0x1e, 0xab, 0x42, 0x32, + 0xa4, 0xd6, 0x54, 0xaa, 0x47, 0x9f, 0x40, 0x59, 0xd8, 0x34, 0xa5, 0x06, 0x5b, 0x78, 0xd4, 0xaf, + 0xa9, 0x8d, 0x74, 0xab, 0xb2, 0xbb, 0x2e, 0x17, 0xb2, 0x1f, 0xc0, 0x7b, 0x26, 0xc3, 0x25, 0xce, + 0x93, 0xdf, 0x3e, 0xda, 0x86, 0x82, 0x6d, 0xbc, 0x21, 0x73, 0xc3, 0x63, 0x7e, 0x6d, 0xbd, 0xa1, + 0xb4, 0xca, 0x38, 0x6f, 0x1b, 0x6f, 0x8e, 0xf8, 0x37, 0xda, 0x81, 0x0d, 0xc7, 0x25, 0xa6, 0x33, + 0xb5, 0xcc, 0xd3, 0x19, 0x23, 0x8b, 0xf9, 0xc4, 0x60, 0xd4, 0xaf, 0x21, 0x61, 0xc3, 0xba, 0xe3, + 0xea, 0x52, 0x72, 0x1c, 0x08, 0xea, 0x5d, 0xb8, 0xbd, 0x7a, 0x7d, 0x3c, 0x82, 0xf8, 0x01, 0xf1, + 0xa0, 0xca, 0x60, 0xfe, 0x13, 0x6d, 0x42, 0xf6, 0x95, 0x61, 0x2d, 0xa8, 0x88, 0xaa, 0x12, 0x0e, + 0x3e, 0x7e, 0x91, 0xfa, 0x4c, 0x69, 0xce, 0x60, 0x63, 0xe4, 0x19, 0xe3, 0xb3, 0x0b, 0x81, 0x79, + 0x31, 0xae, 0x94, 0xcb, 0x71, 0x75, 0x85, 0xbd, 0xa9, 0x2b, 0xec, 0x6d, 0x7e, 0x05, 0x55, 0x71, + 0xc2, 0xfb, 0x94, 0x5e, 0x17, 0xfe, 0x5b, 0xc0, 0x83, 0x5b, 0x44, 0x42, 0x90, 0x02, 0x72, 0x86, + 0xcd, 0x83, 0xa0, 0x39, 0x01, 0x75, 0x39, 0xde, 0x9f, 0xbb, 0x8e, 0x4f, 0x79, 0x6c, 0x73, 0x07, + 0xe0, 0x1e, 0xcc, 0x03, 0x44, 0x84, 0x86, 0x22, 0x46, 0x55, 0x24, 0xbe, 0x4f, 0xa9, 0x08, 0x8e, + 0x07, 0x41, 0x3c, 0x12, 0xcb, 0x1d, 0x9f, 0xf1, 0x24, 0x60, 0x9c, 0x4b, 0xf5, 0x65, 0x0e, 0xf7, + 0xdc, 0xf1, 0x59, 0x97, 0x83, 0xcd, 0x1f, 0x82, 0x3c, 0x35, 0x72, 0xc5, 0x5c, 0xff, 0xc1, 0x76, + 0x34, 0x21, 0x2b, 0x7c, 0x51, 0xa8, 0x2d, 0xee, 0x96, 0xe2, 0x4e, 0x8d, 0x03, 0x51, 0xf3, 0x07, + 0xd8, 0x48, 0x28, 0x97, 0xab, 0xa8, 0x43, 0x7e, 0xee, 0x51, 0xd3, 0x36, 0x4e, 0xa9, 0xd4, 0x1c, + 0x7d, 0xa3, 0x16, 0xac, 0x4d, 0x0d, 0xd3, 0x5a, 0x78, 0xa1, 0xe2, 0x4a, 0xe8, 0x64, 0x01, 0x8a, + 0x43, 0x71, 0xf3, 0x0e, 0xd4, 0x31, 0xf5, 0x29, 0x3b, 0x34, 0x7d, 0xdf, 0x74, 0x9d, 0x8e, 0xeb, + 0x30, 0xcf, 0xb5, 0xe4, 0x0a, 0x9a, 0x77, 0x61, 0x7b, 0xa5, 0x34, 0x30, 0x81, 0x0f, 0xfe, 0x66, + 0x41, 0xbd, 0xf3, 0xd5, 0x83, 0xbf, 0x81, 0xed, 0x95, 0x52, 0x69, 0xff, 0x87, 0x90, 0x9d, 0x1b, + 0xa6, 0xc7, 0xcf, 0x9e, 0x07, 0xe5, 0xed, 0x58, 0x50, 0x1e, 0x19, 0xa6, 0x77, 0x60, 0xfa, 0xcc, + 0xf5, 0xce, 0x71, 0x40, 0x7a, 0x96, 0xc9, 0x2b, 0x6a, 0xaa, 0xf9, 0x07, 0x05, 0x8a, 0x31, 0x21, + 0x0f, 0x0d, 0xc7, 0x9d, 0x50, 0x32, 0xf5, 0x5c, 0x3b, 0xdc, 0x04, 0x0e, 0xec, 0x7b, 0xae, 0xcd, + 0x7d, 0x42, 0x08, 0x99, 0x2b, 0x1d, 0x38, 0xc7, 0x3f, 0x47, 0x2e, 0xfa, 0x08, 0xd6, 0x66, 0x81, + 0x02, 0x91, 0x36, 0x8b, 0xbb, 0x1b, 0x17, 0xe6, 0xee, 0x1a, 0xcc, 0xc0, 0x21, 0xe7, 0x59, 0x26, + 0x9f, 0x56, 0x33, 0xcf, 0x32, 0xf9, 0x8c, 0x9a, 0x7d, 0x96, 0xc9, 0x67, 0xd5, 0xdc, 0xb3, 0x4c, + 0x3e, 0xa7, 0xae, 0x35, 0xff, 0xa9, 0x40, 0x3e, 0x64, 0x73, 0x4b, 0xf8, 0x96, 0x12, 0xee, 0x17, + 0xd2, 0x99, 0xf2, 0x1c, 0x18, 0x99, 0x36, 0x45, 0x0d, 0x28, 0x09, 0x61, 0xd2, 0x45, 0x81, 0x63, + 0x6d, 0xe1, 0xa6, 0x22, 0x9f, 0x87, 0x0c, 0xe1, 0x8f, 0x19, 0x99, 0xcf, 0x03, 0x4a, 0x58, 0xb5, + 0xfc, 0xc5, 0x78, 0x4c, 0x7d, 0x3f, 0x98, 0x25, 0x1b, 0x50, 0x24, 0x26, 0x26, 0x7a, 0x00, 0xd5, + 0x90, 0x12, 0xce, 0x95, 0x0b, 0xfc, 0x55, 0xc2, 0x72, 0xba, 0x16, 0xa8, 0x71, 0x9e, 0xbd, 0xac, + 0x20, 0x95, 0x25, 0x91, 0x4f, 0x1a, 0x2c, 0xbe, 0xd9, 0x80, 0x7b, 0x4f, 0x2f, 0x7a, 0x41, 0xc7, + 0x75, 0xa6, 0xe6, 0x69, 0x78, 0xd8, 0xdf, 0xc3, 0xfd, 0x2b, 0x19, 0xf2, 0xc0, 0x3f, 0x85, 0xdc, + 0x58, 0x20, 0x62, 0x7f, 0x8a, 0xbb, 0xf7, 0x63, 0xbb, 0xbe, 0x72, 0xa0, 0xa4, 0x37, 0x5f, 0xc2, + 0xbd, 0xe1, 0xb5, 0xb3, 0xff, 0xf7, 0xaa, 0xdf, 0x85, 0xfb, 0xc3, 0xeb, 0xcd, 0x6e, 0xfe, 0x36, + 0x05, 0x9b, 0xab, 0x08, 0xbc, 0x12, 0xce, 0x0c, 0x6b, 0x4a, 0x2c, 0x73, 0x4a, 0xa3, 0x72, 0x1d, + 0xa4, 0xcf, 0x2a, 0x17, 0xf4, 0xcc, 0x29, 0x0d, 0xeb, 0xf5, 0x43, 0xa8, 0x8a, 0x22, 0xe8, 0xb9, + 0x27, 0xc6, 0x89, 0x69, 0x99, 0x2c, 0x48, 0x24, 0x29, 0x5c, 0x99, 0xb9, 0xf3, 0xa3, 0x25, 0x8a, + 0x6e, 0x43, 0xee, 0x35, 0xe5, 0x09, 0x50, 0x34, 0x25, 0x29, 0x2c, 0xbf, 0xd0, 0x27, 0xb0, 0x65, + 0x1b, 0x6f, 0x4c, 0x7b, 0x61, 0x93, 0x65, 0x2b, 0xe1, 0x2f, 0x2c, 0xe6, 0x0b, 0x57, 0x29, 0xe3, + 0x5b, 0x52, 0x1c, 0xa5, 0x64, 0x21, 0x44, 0x1d, 0xb8, 0x67, 0x9b, 0x8e, 0x18, 0x27, 0x43, 0x9e, + 0x78, 0xd4, 0x32, 0xde, 0x10, 0xd3, 0x61, 0xd4, 0x7b, 0x65, 0x58, 0xc2, 0x8d, 0x32, 0x78, 0x5b, + 0xb2, 0xc2, 0x04, 0xc1, 0x39, 0xba, 0xa4, 0x34, 0x7f, 0x0d, 0x5b, 0x22, 0x92, 0x63, 0x86, 0x86, + 0x3b, 0xcf, 0xfd, 0xde, 0x73, 0x6d, 0xc2, 0x43, 0x2b, 0x8c, 0x40, 0x0e, 0xf4, 0xdd, 0x09, 0xe5, + 0x11, 0xc8, 0xdc, 0x40, 0x24, 0x23, 0x90, 0xb9, 0x42, 0x10, 0xef, 0xcd, 0xd2, 0x89, 0xde, 0xac, + 0x79, 0x06, 0xb5, 0xcb, 0x73, 0x49, 0x0f, 0x6a, 0x40, 0x31, 0xbe, 0x83, 0x7c, 0x3a, 0x05, 0xc7, + 0xa1, 0x78, 0x68, 0xa7, 0x6e, 0x0e, 0xed, 0xe6, 0xdf, 0x15, 0x58, 0xdf, 0x5b, 0x98, 0xd6, 0x24, + 0x91, 0xb7, 0xe3, 0xd6, 0x29, 0xc9, 0xce, 0x71, 0x55, 0x5b, 0x98, 0x5a, 0xd9, 0x16, 0x7e, 0xb8, + 0xa2, 0xaf, 0x4a, 0x8b, 0xbe, 0x2a, 0xb5, 0xa2, 0xab, 0xba, 0x0f, 0xc5, 0x65, 0x93, 0xc4, 0x8f, + 0x34, 0xdd, 0x2a, 0x61, 0x98, 0x85, 0x1d, 0x92, 0x7f, 0xa9, 0xcb, 0xcc, 0x5e, 0xea, 0x32, 0x9b, + 0x9f, 0x01, 0x8a, 0xaf, 0x45, 0xee, 0x59, 0x54, 0x61, 0x94, 0xab, 0x2b, 0xcc, 0x1d, 0xa8, 0x0f, + 0x17, 0x27, 0xfe, 0xd8, 0x33, 0x4f, 0xe8, 0x01, 0xb3, 0xc6, 0xda, 0x2b, 0xea, 0x30, 0x3f, 0x0c, + 0xed, 0x7f, 0x65, 0xa0, 0x10, 0xa1, 0xbc, 0x80, 0x9b, 0xce, 0xd8, 0xb5, 0xc3, 0x75, 0x39, 0xd4, + 0xe2, 0x4b, 0x0b, 0xfc, 0x7e, 0x3d, 0x14, 0x75, 0x02, 0x89, 0x3e, 0xe1, 0xfc, 0xc4, 0x3e, 0x48, + 0x7e, 0x2a, 0xe0, 0xc7, 0xb7, 0x21, 0xe0, 0xb7, 0x40, 0x8d, 0xf4, 0xcf, 0x98, 0x35, 0x8e, 0xf6, + 0x0d, 0x57, 0x42, 0x9c, 0x1b, 0x13, 0x30, 0x23, 0xcd, 0x21, 0x33, 0x13, 0x30, 0x43, 0x5c, 0x32, + 0xdf, 0x85, 0x12, 0xcf, 0x98, 0x3e, 0x33, 0xec, 0x39, 0x71, 0x7c, 0xe9, 0xf2, 0xc5, 0x08, 0xeb, + 0xfb, 0xe8, 0x4b, 0x00, 0xca, 0xd7, 0x47, 0xd8, 0xf9, 0x9c, 0x8a, 0xa4, 0x59, 0xd9, 0xbd, 0x17, + 0xf3, 0x9d, 0x68, 0x03, 0x76, 0xc4, 0xbf, 0xa3, 0xf3, 0x39, 0xc5, 0x05, 0x1a, 0xfe, 0x44, 0x5f, + 0x41, 0x79, 0xea, 0x7a, 0xaf, 0x0d, 0x6f, 0x42, 0x04, 0x28, 0x0b, 0xcb, 0x56, 0x4c, 0xc3, 0x7e, + 0x20, 0x17, 0xc3, 0x0f, 0xde, 0xc1, 0xa5, 0x69, 0xec, 0x1b, 0x3d, 0x07, 0x14, 0x8e, 0x17, 0x75, + 0x20, 0x50, 0x92, 0x17, 0x4a, 0xb6, 0x2f, 0x2b, 0xe1, 0x51, 0x1a, 0x2a, 0x52, 0xa7, 0x17, 0x30, + 0xf4, 0x39, 0x94, 0x7c, 0xca, 0x98, 0x45, 0xa5, 0x9a, 0x82, 0x50, 0x73, 0x3b, 0xd1, 0xf5, 0x72, + 0x71, 0xa8, 0xa1, 0xe8, 0x2f, 0x3f, 0xd1, 0x1e, 0x54, 0x2d, 0xd3, 0x39, 0x8b, 0x9b, 0x01, 0x62, + 0x7c, 0x2d, 0x36, 0xbe, 0x67, 0x3a, 0x67, 0x71, 0x1b, 0xca, 0x56, 0x1c, 0x68, 0x7e, 0x01, 0x85, + 0x68, 0x97, 0x50, 0x11, 0xd6, 0x8e, 0xfb, 0xcf, 0xfb, 0x83, 0x6f, 0xfb, 0xea, 0x3b, 0x28, 0x0f, + 0x99, 0xa1, 0xd6, 0xef, 0xaa, 0x0a, 0x87, 0xb1, 0xd6, 0xd1, 0xf4, 0x17, 0x9a, 0x9a, 0xe2, 0x1f, + 0xfb, 0x03, 0xfc, 0x6d, 0x1b, 0x77, 0xd5, 0xf4, 0xde, 0x1a, 0x64, 0xc5, 0xbc, 0xcd, 0xbf, 0x28, + 0x90, 0x17, 0x27, 0xe8, 0x4c, 0x5d, 0xf4, 0x13, 0x88, 0x9c, 0x4b, 0x94, 0x3f, 0xde, 0x92, 0x09, + 0xaf, 0x2b, 0xe3, 0xc8, 0x61, 0x46, 0x12, 0xe7, 0xe4, 0xc8, 0x35, 0x22, 0x72, 0x2a, 0x20, 0x87, + 0x82, 0x88, 0xfc, 0x28, 0xa6, 0x39, 0x91, 0x95, 0x32, 0xb8, 0x1a, 0x0a, 0xc2, 0x1a, 0x1c, 0xbf, + 0xfd, 0x24, 0x6a, 0x75, 0xec, 0xf6, 0x23, 0xb9, 0xcd, 0x4f, 0xa1, 0x14, 0x3f, 0x73, 0xf4, 0x10, + 0x32, 0xa6, 0x33, 0x75, 0x65, 0x20, 0x6e, 0x5c, 0x70, 0x2e, 0xbe, 0x48, 0x2c, 0x08, 0x4d, 0x04, + 0xea, 0xc5, 0x73, 0x6e, 0x96, 0xa1, 0x18, 0x3b, 0xb4, 0xe6, 0x3f, 0x14, 0x28, 0x27, 0x0e, 0xe1, + 0xad, 0xb5, 0xa3, 0x2f, 0xa1, 0xf4, 0xda, 0xf4, 0x28, 0x89, 0x37, 0x88, 0x95, 0xdd, 0x7a, 0xb2, + 0x41, 0x0c, 0xff, 0xef, 0xb8, 0x13, 0x8a, 0x8b, 0x9c, 0x2f, 0x01, 0xf4, 0x4b, 0xa8, 0x84, 0x85, + 0x64, 0x42, 0x99, 0x61, 0x5a, 0x62, 0xab, 0x2a, 0x09, 0xf7, 0x90, 0xdc, 0xae, 0x90, 0xe3, 0xf2, + 0x34, 0xfe, 0x89, 0x3e, 0x58, 0x2a, 0xf0, 0x99, 0x67, 0x3a, 0xa7, 0x62, 0xff, 0x0a, 0x11, 0x6d, + 0x28, 0x40, 0xde, 0xea, 0x95, 0x65, 0x2d, 0x1b, 0x32, 0x83, 0x2d, 0x7c, 0xf4, 0x11, 0x64, 0x7d, + 0x66, 0xc8, 0x4c, 0x56, 0x49, 0xc4, 0x56, 0x8c, 0x48, 0x71, 0xc0, 0x4a, 0xf4, 0xc7, 0xa9, 0x4b, + 0xfd, 0x71, 0x96, 0x67, 0x8c, 0x20, 0xd1, 0x16, 0x77, 0x91, 0x5c, 0xfc, 0xc1, 0xa8, 0xd7, 0x69, + 0x33, 0x46, 0xed, 0x39, 0xc3, 0x01, 0x41, 0xf6, 0x3f, 0x5f, 0x01, 0x74, 0x4c, 0x6f, 0xbc, 0x30, + 0xd9, 0x73, 0x7a, 0xce, 0xcb, 0x5a, 0x98, 0xd1, 0x83, 0xb4, 0x97, 0x1b, 0x07, 0x59, 0x7c, 0x0b, + 0xd6, 0xc2, 0x44, 0x14, 0xe4, 0xb7, 0xdc, 0x4c, 0x24, 0xa0, 0xe6, 0x5f, 0x33, 0xb0, 0x2d, 0x8f, + 0x34, 0x38, 0x0d, 0x46, 0xbd, 0x31, 0x9d, 0x47, 0x17, 0xa7, 0xa7, 0xb0, 0xb9, 0x4c, 0xaa, 0xc1, + 0x44, 0x24, 0xbc, 0x8c, 0x15, 0x77, 0x6f, 0xc5, 0x56, 0xba, 0x34, 0x03, 0xa3, 0x28, 0xd9, 0x2e, + 0x4d, 0x7b, 0x12, 0x53, 0x64, 0xd8, 0xee, 0xc2, 0x91, 0x2e, 0x1a, 0x64, 0x3c, 0xb4, 0x74, 0x67, + 0x2e, 0x12, 0x1e, 0xfd, 0x10, 0x22, 0x27, 0x27, 0xf4, 0xcd, 0xdc, 0xf4, 0xce, 0x45, 0xf6, 0x2b, + 0x2f, 0xd3, 0xad, 0x26, 0xd0, 0x4b, 0xb7, 0x99, 0xd4, 0xe5, 0xdb, 0xcc, 0xe7, 0x50, 0x8f, 0xa2, + 0x43, 0x3e, 0x74, 0xd0, 0x49, 0x54, 0xfd, 0xd6, 0x84, 0x0d, 0x5b, 0x21, 0x03, 0x87, 0x04, 0x59, + 0x02, 0x9f, 0xc0, 0x66, 0x2c, 0xb4, 0x96, 0xa6, 0x07, 0x91, 0x88, 0x96, 0xd1, 0x15, 0x37, 0x3d, + 0x1a, 0x21, 0x4d, 0x0f, 0x7a, 0xa1, 0x28, 0xff, 0x4b, 0xd3, 0x7f, 0x05, 0x95, 0x0b, 0x0f, 0x01, + 0x79, 0x71, 0xee, 0x3f, 0xbf, 0x9c, 0x59, 0x57, 0x1d, 0xcf, 0xce, 0x8a, 0xd7, 0x80, 0xf2, 0x38, + 0xf1, 0x12, 0x70, 0x17, 0xc0, 0x75, 0x4c, 0xd7, 0x21, 0x27, 0x96, 0x7b, 0x22, 0x12, 0x6e, 0x09, + 0x17, 0x04, 0xb2, 0x67, 0xb9, 0x27, 0xf5, 0xaf, 0x01, 0xfd, 0x8f, 0x37, 0xee, 0xbf, 0x29, 0x70, + 0x67, 0xb5, 0x89, 0xb2, 0xce, 0xff, 0xdf, 0x5c, 0xe8, 0x73, 0xc8, 0x19, 0x63, 0x66, 0xba, 0x8e, + 0xcc, 0x0c, 0xef, 0xc5, 0x86, 0x62, 0xea, 0xbb, 0xd6, 0x2b, 0x7a, 0xe0, 0x5a, 0x13, 0x69, 0x4c, + 0x5b, 0x50, 0xb1, 0x1c, 0x92, 0x08, 0xba, 0x74, 0x32, 0xe8, 0x1e, 0xfd, 0x2e, 0x03, 0xe5, 0x44, + 0x66, 0x48, 0x96, 0x86, 0x32, 0x14, 0xfa, 0x03, 0xd2, 0xd5, 0x46, 0x6d, 0xbd, 0xa7, 0x2a, 0x48, + 0x85, 0xd2, 0xa0, 0xaf, 0x0f, 0xfa, 0xa4, 0xab, 0x75, 0x06, 0x5d, 0x5e, 0x24, 0x6e, 0xc1, 0x7a, + 0x4f, 0xef, 0x3f, 0x27, 0xfd, 0xc1, 0x88, 0x68, 0x3d, 0xfd, 0xa9, 0xbe, 0xd7, 0xd3, 0xd4, 0x34, + 0xda, 0x04, 0x75, 0xd0, 0x27, 0x9d, 0x83, 0xb6, 0xde, 0x27, 0x23, 0xfd, 0x50, 0x1b, 0x1c, 0x8f, + 0xd4, 0x0c, 0x47, 0x79, 0x34, 0x13, 0xed, 0xbb, 0x8e, 0xa6, 0x75, 0x87, 0xe4, 0xb0, 0xfd, 0x9d, + 0x9a, 0x45, 0x35, 0xd8, 0xd4, 0xfb, 0xc3, 0xe3, 0xfd, 0x7d, 0xbd, 0xa3, 0x6b, 0xfd, 0x11, 0xd9, + 0x6b, 0xf7, 0xda, 0xfd, 0x8e, 0xa6, 0xe6, 0xd0, 0x6d, 0x40, 0x7a, 0xbf, 0x33, 0x38, 0x3c, 0xea, + 0x69, 0x23, 0x8d, 0x84, 0xc5, 0x68, 0x0d, 0x6d, 0x40, 0x55, 0xe8, 0x69, 0x77, 0xbb, 0x64, 0xbf, + 0xad, 0xf7, 0xb4, 0xae, 0x9a, 0xe7, 0x96, 0x48, 0xc6, 0x90, 0x74, 0xf5, 0x61, 0x7b, 0x8f, 0xc3, + 0x05, 0x3e, 0xa7, 0xde, 0x7f, 0x31, 0xd0, 0x3b, 0x1a, 0xe9, 0x70, 0xb5, 0x1c, 0x05, 0x4e, 0x0e, + 0xd1, 0xe3, 0x7e, 0x57, 0xc3, 0x47, 0x6d, 0xbd, 0xab, 0x16, 0xd1, 0x36, 0x6c, 0x85, 0xb0, 0xf6, + 0xdd, 0x91, 0x8e, 0x5f, 0x92, 0xd1, 0x60, 0x40, 0x86, 0x83, 0x41, 0x5f, 0x2d, 0xc5, 0x35, 0xf1, + 0xd5, 0x0e, 0x8e, 0xb4, 0xbe, 0x5a, 0x46, 0x5b, 0xb0, 0x71, 0x78, 0x74, 0x44, 0x42, 0x49, 0xb8, + 0xd8, 0x0a, 0xa7, 0xb7, 0xbb, 0x5d, 0xac, 0x0d, 0x87, 0xe4, 0x50, 0x1f, 0x1e, 0xb6, 0x47, 0x9d, + 0x03, 0xb5, 0xca, 0x97, 0x34, 0xd4, 0x46, 0x64, 0x34, 0x18, 0xb5, 0x7b, 0x4b, 0x5c, 0xe5, 0x06, + 0x2d, 0x71, 0x3e, 0x69, 0x6f, 0xf0, 0xad, 0xba, 0xce, 0x37, 0x9c, 0xc3, 0x83, 0x17, 0xd2, 0x44, + 0xc4, 0xd7, 0x2e, 0x8f, 0x27, 0x9c, 0x53, 0xdd, 0xe0, 0xa0, 0xde, 0x7f, 0xd1, 0xee, 0xe9, 0x5d, + 0xf2, 0x5c, 0x7b, 0x29, 0x8a, 0xf9, 0x26, 0x07, 0x03, 0xcb, 0xc8, 0x11, 0x1e, 0x3c, 0xe5, 0x86, + 0xa8, 0xb7, 0x10, 0x82, 0x4a, 0x47, 0xc7, 0x9d, 0xe3, 0x5e, 0x1b, 0x13, 0x3c, 0x38, 0x1e, 0x69, + 0xea, 0xed, 0x47, 0x7f, 0x56, 0xa0, 0x14, 0x4f, 0xd6, 0xfc, 0xd4, 0xf5, 0x3e, 0xd9, 0xef, 0xe9, + 0x4f, 0x0f, 0x46, 0x81, 0x13, 0x0c, 0x8f, 0x3b, 0xfc, 0xc8, 0x34, 0xde, 0x24, 0x20, 0xa8, 0x04, + 0x9b, 0x1e, 0x2d, 0x36, 0xc5, 0xe7, 0x92, 0x58, 0x7f, 0x20, 0xf5, 0xa6, 0xb9, 0xf1, 0x12, 0xd4, + 0x30, 0x1e, 0x60, 0x35, 0x83, 0xde, 0x87, 0x86, 0x44, 0xf8, 0xb9, 0x62, 0xac, 0x75, 0x46, 0xe4, + 0xa8, 0xfd, 0xf2, 0x90, 0x1f, 0x7b, 0xe0, 0x64, 0x43, 0x35, 0x8b, 0xee, 0xc3, 0x76, 0xc4, 0x5a, + 0xe5, 0x17, 0x8f, 0xbe, 0x80, 0xda, 0x55, 0x4e, 0x8f, 0x00, 0x72, 0x43, 0x6d, 0x34, 0xea, 0x69, + 0x41, 0x63, 0xb3, 0x1f, 0x38, 0x2e, 0x40, 0x0e, 0x6b, 0xc3, 0xe3, 0x43, 0x4d, 0x4d, 0xed, 0xfe, + 0x89, 0x7f, 0x88, 0xe8, 0x41, 0x5f, 0x43, 0x39, 0xf6, 0xd6, 0xf8, 0x62, 0x17, 0xdd, 0xbd, 0xf6, + 0x15, 0xb2, 0x1e, 0xbe, 0xd8, 0x48, 0xf8, 0x89, 0x82, 0xf6, 0xa0, 0x12, 0x7f, 0x74, 0x7b, 0xb1, + 0x8b, 0xe2, 0x0d, 0xea, 0x8a, 0xf7, 0xb8, 0x15, 0x3a, 0x9e, 0x83, 0xaa, 0xf9, 0xcc, 0xb4, 0x79, + 0x9d, 0x94, 0xcf, 0x62, 0xa8, 0x1e, 0x0f, 0xf0, 0xe4, 0x5b, 0x5b, 0x7d, 0x7b, 0xa5, 0x4c, 0xa6, + 0x9c, 0x6f, 0x78, 0x4f, 0x12, 0x3d, 0x4c, 0x5d, 0x5a, 0x50, 0xf2, 0x35, 0xac, 0x7e, 0xef, 0x2a, + 0xb1, 0xbc, 0x67, 0xa7, 0x7f, 0x9f, 0xe2, 0x6b, 0x2c, 0xc7, 0x64, 0x2b, 0x76, 0xe9, 0x82, 0xd2, + 0x15, 0x95, 0x1b, 0x4d, 0x60, 0x63, 0xc5, 0xa3, 0x15, 0xfa, 0x20, 0x99, 0xc7, 0xae, 0x78, 0xf2, + 0xaa, 0x3f, 0xb8, 0x89, 0x26, 0x17, 0x3f, 0x81, 0x8d, 0x15, 0xaf, 0x5b, 0x89, 0x59, 0xae, 0x7e, + 0x1b, 0x4b, 0xcc, 0x72, 0xdd, 0x23, 0xd9, 0x1c, 0xb6, 0xae, 0x78, 0x56, 0x41, 0x3f, 0x8e, 0xa9, + 0xb8, 0xfe, 0x71, 0xa6, 0xfe, 0xe8, 0x6d, 0xa8, 0xcb, 0x19, 0x87, 0x6f, 0x31, 0xe3, 0xf0, 0xed, + 0x67, 0xbc, 0xe1, 0x81, 0x05, 0xfd, 0x00, 0xea, 0xc5, 0x1b, 0x3f, 0x6a, 0x5e, 0xdc, 0x9f, 0xcb, + 0x4f, 0x0f, 0xf5, 0xf7, 0xae, 0xe5, 0x48, 0xe5, 0x3a, 0xc0, 0xf2, 0x52, 0x8c, 0xee, 0xc4, 0x86, + 0x5c, 0xba, 0xf7, 0xd7, 0xef, 0x5e, 0x21, 0x95, 0xaa, 0x46, 0xb0, 0xb1, 0xe2, 0x96, 0x9c, 0x38, + 0xf1, 0xab, 0x6f, 0xd1, 0xf5, 0xcd, 0x55, 0x97, 0xc9, 0x27, 0x0a, 0x3a, 0x0c, 0x82, 0x28, 0xfc, + 0x23, 0xc1, 0x0d, 0x59, 0xa1, 0xb6, 0xba, 0xe9, 0x5d, 0xf8, 0x22, 0x7c, 0x9e, 0x28, 0x68, 0x00, + 0xa5, 0x78, 0x26, 0xb8, 0x31, 0x45, 0xdc, 0xa8, 0x70, 0x0a, 0xd5, 0x44, 0xc3, 0xe1, 0x7a, 0xe8, + 0xe1, 0x8d, 0x6d, 0x53, 0xb0, 0x63, 0x09, 0x2f, 0xbf, 0xa6, 0xbf, 0x6a, 0x29, 0x4f, 0x94, 0xbd, + 0x8f, 0xbf, 0x7f, 0x7c, 0x6a, 0xb2, 0xd9, 0xe2, 0x64, 0x67, 0xec, 0xda, 0x8f, 0xc5, 0xdf, 0x00, + 0x1c, 0xd3, 0x39, 0x75, 0x28, 0x7b, 0xed, 0x7a, 0x67, 0x8f, 0x2d, 0x67, 0xf2, 0x58, 0x84, 0xfa, + 0xe3, 0x48, 0xe5, 0x49, 0x4e, 0xfc, 0x95, 0xf0, 0xa7, 0xff, 0x0e, 0x00, 0x00, 0xff, 0xff, 0xff, + 0x7e, 0x76, 0x2e, 0x55, 0x1c, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -2260,6 +2517,13 @@ type RouterClient interface { //It is a development feature. QueryMissionControl(ctx context.Context, in *QueryMissionControlRequest, opts ...grpc.CallOption) (*QueryMissionControlResponse, error) // + //GetMissionControlConfig returns mission control's current config. + GetMissionControlConfig(ctx context.Context, in *GetMissionControlConfigRequest, opts ...grpc.CallOption) (*GetMissionControlConfigResponse, error) + // + //SetMissionControlConfig will set mission control's config, if the config + //provided is valid. + SetMissionControlConfig(ctx context.Context, in *SetMissionControlConfigRequest, opts ...grpc.CallOption) (*SetMissionControlConfigResponse, error) + // //QueryProbability returns the current success probability estimate for a //given node pair and amount. QueryProbability(ctx context.Context, in *QueryProbabilityRequest, opts ...grpc.CallOption) (*QueryProbabilityResponse, error) @@ -2408,6 +2672,24 @@ func (c *routerClient) QueryMissionControl(ctx context.Context, in *QueryMission return out, nil } +func (c *routerClient) GetMissionControlConfig(ctx context.Context, in *GetMissionControlConfigRequest, opts ...grpc.CallOption) (*GetMissionControlConfigResponse, error) { + out := new(GetMissionControlConfigResponse) + err := c.cc.Invoke(ctx, "/routerrpc.Router/GetMissionControlConfig", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *routerClient) SetMissionControlConfig(ctx context.Context, in *SetMissionControlConfigRequest, opts ...grpc.CallOption) (*SetMissionControlConfigResponse, error) { + out := new(SetMissionControlConfigResponse) + err := c.cc.Invoke(ctx, "/routerrpc.Router/SetMissionControlConfig", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + func (c *routerClient) QueryProbability(ctx context.Context, in *QueryProbabilityRequest, opts ...grpc.CallOption) (*QueryProbabilityResponse, error) { out := new(QueryProbabilityResponse) err := c.cc.Invoke(ctx, "/routerrpc.Router/QueryProbability", in, out, opts...) @@ -2592,6 +2874,13 @@ type RouterServer interface { //It is a development feature. QueryMissionControl(context.Context, *QueryMissionControlRequest) (*QueryMissionControlResponse, error) // + //GetMissionControlConfig returns mission control's current config. + GetMissionControlConfig(context.Context, *GetMissionControlConfigRequest) (*GetMissionControlConfigResponse, error) + // + //SetMissionControlConfig will set mission control's config, if the config + //provided is valid. + SetMissionControlConfig(context.Context, *SetMissionControlConfigRequest) (*SetMissionControlConfigResponse, error) + // //QueryProbability returns the current success probability estimate for a //given node pair and amount. QueryProbability(context.Context, *QueryProbabilityRequest) (*QueryProbabilityResponse, error) @@ -2647,6 +2936,12 @@ func (*UnimplementedRouterServer) ResetMissionControl(ctx context.Context, req * func (*UnimplementedRouterServer) QueryMissionControl(ctx context.Context, req *QueryMissionControlRequest) (*QueryMissionControlResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method QueryMissionControl not implemented") } +func (*UnimplementedRouterServer) GetMissionControlConfig(ctx context.Context, req *GetMissionControlConfigRequest) (*GetMissionControlConfigResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetMissionControlConfig not implemented") +} +func (*UnimplementedRouterServer) SetMissionControlConfig(ctx context.Context, req *SetMissionControlConfigRequest) (*SetMissionControlConfigResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method SetMissionControlConfig not implemented") +} func (*UnimplementedRouterServer) QueryProbability(ctx context.Context, req *QueryProbabilityRequest) (*QueryProbabilityResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method QueryProbability not implemented") } @@ -2802,6 +3097,42 @@ func _Router_QueryMissionControl_Handler(srv interface{}, ctx context.Context, d return interceptor(ctx, in, info, handler) } +func _Router_GetMissionControlConfig_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GetMissionControlConfigRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(RouterServer).GetMissionControlConfig(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/routerrpc.Router/GetMissionControlConfig", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(RouterServer).GetMissionControlConfig(ctx, req.(*GetMissionControlConfigRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Router_SetMissionControlConfig_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(SetMissionControlConfigRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(RouterServer).SetMissionControlConfig(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/routerrpc.Router/SetMissionControlConfig", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(RouterServer).SetMissionControlConfig(ctx, req.(*SetMissionControlConfigRequest)) + } + return interceptor(ctx, in, info, handler) +} + func _Router_QueryProbability_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(QueryProbabilityRequest) if err := dec(in); err != nil { @@ -2951,6 +3282,14 @@ var _Router_serviceDesc = grpc.ServiceDesc{ MethodName: "QueryMissionControl", Handler: _Router_QueryMissionControl_Handler, }, + { + MethodName: "GetMissionControlConfig", + Handler: _Router_GetMissionControlConfig_Handler, + }, + { + MethodName: "SetMissionControlConfig", + Handler: _Router_SetMissionControlConfig_Handler, + }, { MethodName: "QueryProbability", Handler: _Router_QueryProbability_Handler, diff --git a/lnrpc/routerrpc/router.pb.gw.go b/lnrpc/routerrpc/router.pb.gw.go index 23350311..80638c12 100644 --- a/lnrpc/routerrpc/router.pb.gw.go +++ b/lnrpc/routerrpc/router.pb.gw.go @@ -222,6 +222,24 @@ func local_request_Router_QueryMissionControl_0(ctx context.Context, marshaler r } +func request_Router_GetMissionControlConfig_0(ctx context.Context, marshaler runtime.Marshaler, client RouterClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq GetMissionControlConfigRequest + var metadata runtime.ServerMetadata + + msg, err := client.GetMissionControlConfig(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_Router_GetMissionControlConfig_0(ctx context.Context, marshaler runtime.Marshaler, server RouterServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq GetMissionControlConfigRequest + var metadata runtime.ServerMetadata + + msg, err := server.GetMissionControlConfig(ctx, &protoReq) + return msg, metadata, err + +} + func request_Router_QueryProbability_0(ctx context.Context, marshaler runtime.Marshaler, client RouterClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { var protoReq QueryProbabilityRequest var metadata runtime.ServerMetadata @@ -470,6 +488,26 @@ func RegisterRouterHandlerServer(ctx context.Context, mux *runtime.ServeMux, ser }) + mux.Handle("GET", pattern_Router_GetMissionControlConfig_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_Router_GetMissionControlConfig_0(rctx, inboundMarshaler, server, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_Router_GetMissionControlConfig_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + mux.Handle("GET", pattern_Router_QueryProbability_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { ctx, cancel := context.WithCancel(req.Context()) defer cancel() @@ -678,6 +716,26 @@ func RegisterRouterHandlerClient(ctx context.Context, mux *runtime.ServeMux, cli }) + mux.Handle("GET", pattern_Router_GetMissionControlConfig_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_Router_GetMissionControlConfig_0(rctx, inboundMarshaler, client, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_Router_GetMissionControlConfig_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + mux.Handle("GET", pattern_Router_QueryProbability_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { ctx, cancel := context.WithCancel(req.Context()) defer cancel() @@ -754,6 +812,8 @@ var ( pattern_Router_QueryMissionControl_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"v2", "router", "mc"}, "", runtime.AssumeColonVerbOpt(true))) + pattern_Router_GetMissionControlConfig_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"v2", "router", "mccfg"}, "", runtime.AssumeColonVerbOpt(true))) + pattern_Router_QueryProbability_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 1, 0, 4, 1, 5, 4, 1, 0, 4, 1, 5, 5, 1, 0, 4, 1, 5, 6}, []string{"v2", "router", "mc", "probability", "from_node", "to_node", "amt_msat"}, "", runtime.AssumeColonVerbOpt(true))) pattern_Router_BuildRoute_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"v2", "router", "route"}, "", runtime.AssumeColonVerbOpt(true))) @@ -774,6 +834,8 @@ var ( forward_Router_QueryMissionControl_0 = runtime.ForwardResponseMessage + forward_Router_GetMissionControlConfig_0 = runtime.ForwardResponseMessage + forward_Router_QueryProbability_0 = runtime.ForwardResponseMessage forward_Router_BuildRoute_0 = runtime.ForwardResponseMessage diff --git a/lnrpc/routerrpc/router.proto b/lnrpc/routerrpc/router.proto index 8aecab8b..5a5830d0 100644 --- a/lnrpc/routerrpc/router.proto +++ b/lnrpc/routerrpc/router.proto @@ -61,6 +61,19 @@ service Router { rpc QueryMissionControl (QueryMissionControlRequest) returns (QueryMissionControlResponse); + /* + GetMissionControlConfig returns mission control's current config. + */ + rpc GetMissionControlConfig (GetMissionControlConfigRequest) + returns (GetMissionControlConfigResponse); + + /* + SetMissionControlConfig will set mission control's config, if the config + provided is valid. + */ + rpc SetMissionControlConfig (SetMissionControlConfigRequest) + returns (SetMissionControlConfigResponse); + /* QueryProbability returns the current success probability estimate for a given node pair and amount. @@ -354,6 +367,67 @@ message PairData { int64 success_amt_msat = 7; } +message GetMissionControlConfigRequest { +} + +message GetMissionControlConfigResponse { + /* + Mission control's currently active config. + */ + MissionControlConfig config = 1; +} + +message SetMissionControlConfigRequest { + /* + The config to set for mission control. Note that all values *must* be set, + because the full config will be applied. + */ + MissionControlConfig config = 1; +} + +message SetMissionControlConfigResponse { +} + +message MissionControlConfig { + /* + The amount of time mission control will take to restore a penalized node + or channel back to 50% success probability, expressed as a unix timestamp + in seconds. Setting this value to a higher value will penalize failures for + longer, making mission control less likely to route through nodes and + channels that we have previously recorded failures for. + */ + uint64 half_life_seconds = 1; + + /* + The probability of success mission control should assign to hop in a route + where it has no other information available. Higher values will make mission + control more willing to try hops that we have no information about, lower + values will discourage trying these hops. + */ + float hop_probability = 2; + + /* + The importance that mission control should place on historical results, + expressed as a value in [0;1]. Setting this value to 1 will ignore all + historical payments and just use the hop probability to assess the + probability of success for each hop. A zero value ignores hop probability + completely and relies entirely on historical results, unless none are + available. + */ + float weight = 3; + + /* + The maximum number of payment results that mission control will store. + */ + uint32 maximum_payment_results = 4; + + /* + The minimum time that must have passed since the previously recorded failure + before we raise the failure amount. + */ + uint64 minimum_failure_relax_interval = 5; +} + message QueryProbabilityRequest { // The source node pubkey of the pair. bytes from_node = 1; diff --git a/lnrpc/routerrpc/router.swagger.json b/lnrpc/routerrpc/router.swagger.json index 0c630f19..7702fe8e 100644 --- a/lnrpc/routerrpc/router.swagger.json +++ b/lnrpc/routerrpc/router.swagger.json @@ -148,6 +148,29 @@ ] } }, + "/v2/router/mccfg": { + "get": { + "summary": "GetMissionControlConfig returns mission control's current config.", + "operationId": "GetMissionControlConfig", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/routerrpcGetMissionControlConfigResponse" + } + }, + "default": { + "description": "An unexpected error response", + "schema": { + "$ref": "#/definitions/runtimeError" + } + } + }, + "tags": [ + "Router" + ] + } + }, "/v2/router/route": { "post": { "summary": "BuildRoute builds a fully specified route based on a list of hop public\nkeys. It retrieves the relevant channel policies from the graph in order to\ncalculate the correct fees and time locks.", @@ -957,6 +980,15 @@ } } }, + "routerrpcGetMissionControlConfigResponse": { + "type": "object", + "properties": { + "config": { + "$ref": "#/definitions/routerrpcMissionControlConfig", + "description": "Mission control's currently active config." + } + } + }, "routerrpcHtlcEvent": { "type": "object", "properties": { @@ -1060,6 +1092,36 @@ } } }, + "routerrpcMissionControlConfig": { + "type": "object", + "properties": { + "half_life_seconds": { + "type": "string", + "format": "uint64", + "description": "The amount of time mission control will take to restore a penalized node\nor channel back to 50% success probability, expressed as a unix timestamp\nin seconds. Setting this value to a higher value will penalize failures for\nlonger, making mission control less likely to route through nodes and\nchannels that we have previously recorded failures for." + }, + "hop_probability": { + "type": "number", + "format": "float", + "description": "The probability of success mission control should assign to hop in a route \nwhere it has no other information available. Higher values will make mission \ncontrol more willing to try hops that we have no information about, lower \nvalues will discourage trying these hops." + }, + "weight": { + "type": "number", + "format": "float", + "description": "The importance that mission control should place on historical results,\nexpressed as a value in [0;1]. Setting this value to 1 will ignore all\nhistorical payments and just use the hop probability to assess the\nprobability of success for each hop. A zero value ignores hop probability\ncompletely and relies entirely on historical results, unless none are\navailable." + }, + "maximum_payment_results": { + "type": "integer", + "format": "int64", + "description": "The maximum number of payment results that mission control will store." + }, + "minimum_failure_relax_interval": { + "type": "string", + "format": "uint64", + "description": "The minimum time that must have passed since the previously recorded failure\nbefore we raise the failure amount." + } + } + }, "routerrpcPairData": { "type": "object", "properties": { @@ -1363,6 +1425,9 @@ } } }, + "routerrpcSetMissionControlConfigResponse": { + "type": "object" + }, "routerrpcSettleEvent": { "type": "object" }, diff --git a/lnrpc/routerrpc/router_backend.go b/lnrpc/routerrpc/router_backend.go index 74775fc5..a569d41f 100644 --- a/lnrpc/routerrpc/router_backend.go +++ b/lnrpc/routerrpc/router_backend.go @@ -95,6 +95,13 @@ type MissionControl interface { // pair. GetPairHistorySnapshot(fromNode, toNode route.Vertex) routing.TimedPairResult + + // GetConfig gets mission control's current config. + GetConfig() *routing.MissionControlConfig + + // SetConfig sets mission control's config to the values provided, if + // they are valid. + SetConfig(cfg *routing.MissionControlConfig) error } // QueryRoutes attempts to query the daemons' Channel Router for a possible diff --git a/lnrpc/routerrpc/router_backend_test.go b/lnrpc/routerrpc/router_backend_test.go index bd9fee37..f100909a 100644 --- a/lnrpc/routerrpc/router_backend_test.go +++ b/lnrpc/routerrpc/router_backend_test.go @@ -216,6 +216,7 @@ func testQueryRoutes(t *testing.T, useMissionControl bool, useMsat bool) { } type mockMissionControl struct { + MissionControl } func (m *mockMissionControl) GetProbability(fromNode, toNode route.Vertex, diff --git a/lnrpc/routerrpc/router_server.go b/lnrpc/routerrpc/router_server.go index 2aead9e0..e3c0a2ae 100644 --- a/lnrpc/routerrpc/router_server.go +++ b/lnrpc/routerrpc/router_server.go @@ -8,6 +8,7 @@ import ( "os" "path/filepath" "sync/atomic" + "time" "github.com/btcsuite/btcutil" "github.com/grpc-ecosystem/grpc-gateway/runtime" @@ -79,6 +80,13 @@ var ( Entity: "offchain", Action: "read", }}, + "/routerrpc.Router/GetMissionControlConfig": {{ + Entity: "offchain", + Action: "read", + }}, "/routerrpc.Router/SetMissionControlConfig": {{ + Entity: "offchain", + Action: "write", + }}, "/routerrpc.Router/QueryProbability": {{ Entity: "offchain", Action: "read", @@ -391,6 +399,46 @@ func (s *Server) ResetMissionControl(ctx context.Context, return &ResetMissionControlResponse{}, nil } +// GetMissionControlConfig returns our current mission control config. +func (s *Server) GetMissionControlConfig(ctx context.Context, + req *GetMissionControlConfigRequest) (*GetMissionControlConfigResponse, + error) { + + cfg := s.cfg.RouterBackend.MissionControl.GetConfig() + return &GetMissionControlConfigResponse{ + Config: &MissionControlConfig{ + HalfLifeSeconds: uint64(cfg.PenaltyHalfLife.Seconds()), + HopProbability: float32(cfg.AprioriHopProbability), + Weight: float32(cfg.AprioriWeight), + MaximumPaymentResults: uint32(cfg.MaxMcHistory), + MinimumFailureRelaxInterval: uint64(cfg.MinFailureRelaxInterval.Seconds()), + }, + }, nil +} + +// SetMissionControlConfig returns our current mission control config. +func (s *Server) SetMissionControlConfig(ctx context.Context, + req *SetMissionControlConfigRequest) (*SetMissionControlConfigResponse, + error) { + + cfg := &routing.MissionControlConfig{ + ProbabilityEstimatorCfg: routing.ProbabilityEstimatorCfg{ + PenaltyHalfLife: time.Duration( + req.Config.HalfLifeSeconds, + ) * time.Second, + AprioriHopProbability: float64(req.Config.HopProbability), + AprioriWeight: float64(req.Config.Weight), + }, + MaxMcHistory: int(req.Config.MaximumPaymentResults), + MinFailureRelaxInterval: time.Duration( + req.Config.MinimumFailureRelaxInterval, + ) * time.Second, + } + + return &SetMissionControlConfigResponse{}, + s.cfg.RouterBackend.MissionControl.SetConfig(cfg) +} + // QueryMissionControl exposes the internal mission control state to callers. It // is a development feature. func (s *Server) QueryMissionControl(ctx context.Context, diff --git a/lntest/itest/lnd_test.go b/lntest/itest/lnd_test.go index 9b94a671..ac6fe05b 100644 --- a/lntest/itest/lnd_test.go +++ b/lntest/itest/lnd_test.go @@ -12664,6 +12664,10 @@ func testQueryRoutes(net *lntest.NetworkHarness, t *harnessTest) { } } + // While we're here, we test updating mission control's config values + // and assert that they are correctly updated. + testMissionControlCfg(t.t, net.Alice) + // We clean up the test case by closing channels that were created for // the duration of the tests. ctxt, _ = context.WithTimeout(ctxb, channelCloseTimeout) @@ -12674,6 +12678,51 @@ func testQueryRoutes(net *lntest.NetworkHarness, t *harnessTest) { closeChannelAndAssert(ctxt, t, net, carol, chanPointCarol, false) } +// testMissionControlCfg tests getting and setting of a node's mission control +// config, resetting to the original values after testing so that no other +// tests are affected. +func testMissionControlCfg(t *testing.T, node *lntest.HarnessNode) { + ctxb := context.Background() + startCfg, err := node.RouterClient.GetMissionControlConfig( + ctxb, &routerrpc.GetMissionControlConfigRequest{}, + ) + require.NoError(t, err) + + cfg := &routerrpc.MissionControlConfig{ + HalfLifeSeconds: 8000, + HopProbability: 0.8, + Weight: 0.3, + MaximumPaymentResults: 30, + MinimumFailureRelaxInterval: 60, + } + + _, err = node.RouterClient.SetMissionControlConfig( + ctxb, &routerrpc.SetMissionControlConfigRequest{ + Config: cfg, + }, + ) + require.NoError(t, err) + + resp, err := node.RouterClient.GetMissionControlConfig( + ctxb, &routerrpc.GetMissionControlConfigRequest{}, + ) + require.NoError(t, err) + + // Set the hidden fields on the cfg we set so that we can use require + // equal rather than comparing field by field. + cfg.XXX_sizecache = resp.XXX_sizecache + cfg.XXX_NoUnkeyedLiteral = resp.XXX_NoUnkeyedLiteral + cfg.XXX_unrecognized = resp.XXX_unrecognized + require.Equal(t, cfg, resp.Config) + + _, err = node.RouterClient.SetMissionControlConfig( + ctxb, &routerrpc.SetMissionControlConfigRequest{ + Config: startCfg.Config, + }, + ) + require.NoError(t, err) +} + // testRouteFeeCutoff tests that we are able to prevent querying routes and // sending payments that incur a fee higher than the fee limit. func testRouteFeeCutoff(net *lntest.NetworkHarness, t *harnessTest) { diff --git a/routing/mock_test.go b/routing/mock_test.go index a284cf57..9c4f79e5 100644 --- a/routing/mock_test.go +++ b/routing/mock_test.go @@ -104,6 +104,7 @@ func (m *mockPaymentSessionSource) NewPaymentSessionEmpty() PaymentSession { } type mockMissionControl struct { + MissionControl } var _ MissionController = (*mockMissionControl)(nil)