Merge pull request #5033 from robot-dreams/set-channel-status
Add lncli command / RPC for manually setting channel state
This commit is contained in:
commit
65b0bbcd53
94
cmd/lncli/cmd_update_chan_status.go
Normal file
94
cmd/lncli/cmd_update_chan_status.go
Normal file
@ -0,0 +1,94 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
|
||||
"github.com/lightningnetwork/lnd/lnrpc/routerrpc"
|
||||
"github.com/urfave/cli"
|
||||
)
|
||||
|
||||
var updateChanStatusCommand = cli.Command{
|
||||
Name: "updatechanstatus",
|
||||
Category: "Channels",
|
||||
Usage: "Set the status of an existing channel on the network.",
|
||||
Description: `
|
||||
Set the status of an existing channel on the network. The actions can
|
||||
be "enable", "disable", or "auto". If the action changes the status, a
|
||||
message will be broadcast over the network.
|
||||
|
||||
Note that enabling / disabling a channel using this command ONLY affects
|
||||
what's advertised over the network. For example, disabling a channel
|
||||
using this command does not close it.
|
||||
|
||||
If a channel is manually disabled, automatic / background requests to
|
||||
re-enable the channel will be ignored. However, if a channel is
|
||||
manually enabled, automatic / background requests to disable the
|
||||
channel will succeed (such requests are usually made on channel close
|
||||
or when the peer is down).
|
||||
|
||||
The "auto" action restores automatic channel state management. Per
|
||||
the behavior described above, it's only needed to undo the effect of
|
||||
a prior "disable" action, and will be a no-op otherwise.`,
|
||||
ArgsUsage: "funding_txid [output_index] action",
|
||||
Flags: []cli.Flag{
|
||||
cli.StringFlag{
|
||||
Name: "funding_txid",
|
||||
Usage: "the txid of the channel's funding transaction",
|
||||
},
|
||||
cli.IntFlag{
|
||||
Name: "output_index",
|
||||
Usage: "the output index for the funding output of the funding " +
|
||||
"transaction",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "action",
|
||||
Usage: `the action to take: must be one of "enable", "disable", ` +
|
||||
`or "auto"`,
|
||||
},
|
||||
},
|
||||
Action: actionDecorator(updateChanStatus),
|
||||
}
|
||||
|
||||
func updateChanStatus(ctx *cli.Context) error {
|
||||
conn := getClientConn(ctx, false)
|
||||
defer conn.Close()
|
||||
|
||||
if ctx.NArg() == 0 && ctx.NumFlags() == 0 {
|
||||
_ = cli.ShowCommandHelp(ctx, "updatechanstatus")
|
||||
return nil
|
||||
}
|
||||
|
||||
channelPoint, err := parseChannelPoint(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var action routerrpc.ChanStatusAction
|
||||
switch ctx.String("action") {
|
||||
case "enable":
|
||||
action = routerrpc.ChanStatusAction_ENABLE
|
||||
case "disable":
|
||||
action = routerrpc.ChanStatusAction_DISABLE
|
||||
case "auto":
|
||||
action = routerrpc.ChanStatusAction_AUTO
|
||||
default:
|
||||
return errors.New(`action must be one of "enable", "disable", ` +
|
||||
`or "auto"`)
|
||||
}
|
||||
req := &routerrpc.UpdateChanStatusRequest{
|
||||
ChanPoint: channelPoint,
|
||||
Action: action,
|
||||
}
|
||||
|
||||
client := routerrpc.NewRouterClient(conn)
|
||||
ctxb := context.Background()
|
||||
resp, err := client.UpdateChanStatus(ctxb, req)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
printRespJSON(resp)
|
||||
|
||||
return nil
|
||||
}
|
@ -11,5 +11,6 @@ func routerCommands() []cli.Command {
|
||||
buildRouteCommand,
|
||||
getCfgCommand,
|
||||
setCfgCommand,
|
||||
updateChanStatusCommand,
|
||||
}
|
||||
}
|
||||
|
@ -226,6 +226,9 @@ http:
|
||||
# deprecated, no REST endpoint
|
||||
- selector: routerrpc.HtlcInterceptor
|
||||
# request streaming RPC, REST not supported
|
||||
- selector: routerrpc.UpdateChanStatus
|
||||
post: "/v2/router/updatechanstatus"
|
||||
body: "*"
|
||||
|
||||
# signrpc/signer.proto
|
||||
- selector: signrpc.Signer.SignOutputRaw
|
||||
|
@ -197,6 +197,34 @@ func (ResolveHoldForwardAction) EnumDescriptor() ([]byte, []int) {
|
||||
return fileDescriptor_7a0613f69d37b0a5, []int{2}
|
||||
}
|
||||
|
||||
type ChanStatusAction int32
|
||||
|
||||
const (
|
||||
ChanStatusAction_ENABLE ChanStatusAction = 0
|
||||
ChanStatusAction_DISABLE ChanStatusAction = 1
|
||||
ChanStatusAction_AUTO ChanStatusAction = 2
|
||||
)
|
||||
|
||||
var ChanStatusAction_name = map[int32]string{
|
||||
0: "ENABLE",
|
||||
1: "DISABLE",
|
||||
2: "AUTO",
|
||||
}
|
||||
|
||||
var ChanStatusAction_value = map[string]int32{
|
||||
"ENABLE": 0,
|
||||
"DISABLE": 1,
|
||||
"AUTO": 2,
|
||||
}
|
||||
|
||||
func (x ChanStatusAction) String() string {
|
||||
return proto.EnumName(ChanStatusAction_name, int32(x))
|
||||
}
|
||||
|
||||
func (ChanStatusAction) EnumDescriptor() ([]byte, []int) {
|
||||
return fileDescriptor_7a0613f69d37b0a5, []int{3}
|
||||
}
|
||||
|
||||
type HtlcEvent_EventType int32
|
||||
|
||||
const (
|
||||
@ -2259,10 +2287,89 @@ func (m *ForwardHtlcInterceptResponse) GetPreimage() []byte {
|
||||
return nil
|
||||
}
|
||||
|
||||
type UpdateChanStatusRequest struct {
|
||||
ChanPoint *lnrpc.ChannelPoint `protobuf:"bytes,1,opt,name=chan_point,json=chanPoint,proto3" json:"chan_point,omitempty"`
|
||||
Action ChanStatusAction `protobuf:"varint,2,opt,name=action,proto3,enum=routerrpc.ChanStatusAction" json:"action,omitempty"`
|
||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
XXX_sizecache int32 `json:"-"`
|
||||
}
|
||||
|
||||
func (m *UpdateChanStatusRequest) Reset() { *m = UpdateChanStatusRequest{} }
|
||||
func (m *UpdateChanStatusRequest) String() string { return proto.CompactTextString(m) }
|
||||
func (*UpdateChanStatusRequest) ProtoMessage() {}
|
||||
func (*UpdateChanStatusRequest) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_7a0613f69d37b0a5, []int{32}
|
||||
}
|
||||
|
||||
func (m *UpdateChanStatusRequest) XXX_Unmarshal(b []byte) error {
|
||||
return xxx_messageInfo_UpdateChanStatusRequest.Unmarshal(m, b)
|
||||
}
|
||||
func (m *UpdateChanStatusRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||
return xxx_messageInfo_UpdateChanStatusRequest.Marshal(b, m, deterministic)
|
||||
}
|
||||
func (m *UpdateChanStatusRequest) XXX_Merge(src proto.Message) {
|
||||
xxx_messageInfo_UpdateChanStatusRequest.Merge(m, src)
|
||||
}
|
||||
func (m *UpdateChanStatusRequest) XXX_Size() int {
|
||||
return xxx_messageInfo_UpdateChanStatusRequest.Size(m)
|
||||
}
|
||||
func (m *UpdateChanStatusRequest) XXX_DiscardUnknown() {
|
||||
xxx_messageInfo_UpdateChanStatusRequest.DiscardUnknown(m)
|
||||
}
|
||||
|
||||
var xxx_messageInfo_UpdateChanStatusRequest proto.InternalMessageInfo
|
||||
|
||||
func (m *UpdateChanStatusRequest) GetChanPoint() *lnrpc.ChannelPoint {
|
||||
if m != nil {
|
||||
return m.ChanPoint
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *UpdateChanStatusRequest) GetAction() ChanStatusAction {
|
||||
if m != nil {
|
||||
return m.Action
|
||||
}
|
||||
return ChanStatusAction_ENABLE
|
||||
}
|
||||
|
||||
type UpdateChanStatusResponse struct {
|
||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
XXX_sizecache int32 `json:"-"`
|
||||
}
|
||||
|
||||
func (m *UpdateChanStatusResponse) Reset() { *m = UpdateChanStatusResponse{} }
|
||||
func (m *UpdateChanStatusResponse) String() string { return proto.CompactTextString(m) }
|
||||
func (*UpdateChanStatusResponse) ProtoMessage() {}
|
||||
func (*UpdateChanStatusResponse) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_7a0613f69d37b0a5, []int{33}
|
||||
}
|
||||
|
||||
func (m *UpdateChanStatusResponse) XXX_Unmarshal(b []byte) error {
|
||||
return xxx_messageInfo_UpdateChanStatusResponse.Unmarshal(m, b)
|
||||
}
|
||||
func (m *UpdateChanStatusResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||
return xxx_messageInfo_UpdateChanStatusResponse.Marshal(b, m, deterministic)
|
||||
}
|
||||
func (m *UpdateChanStatusResponse) XXX_Merge(src proto.Message) {
|
||||
xxx_messageInfo_UpdateChanStatusResponse.Merge(m, src)
|
||||
}
|
||||
func (m *UpdateChanStatusResponse) XXX_Size() int {
|
||||
return xxx_messageInfo_UpdateChanStatusResponse.Size(m)
|
||||
}
|
||||
func (m *UpdateChanStatusResponse) XXX_DiscardUnknown() {
|
||||
xxx_messageInfo_UpdateChanStatusResponse.DiscardUnknown(m)
|
||||
}
|
||||
|
||||
var xxx_messageInfo_UpdateChanStatusResponse proto.InternalMessageInfo
|
||||
|
||||
func init() {
|
||||
proto.RegisterEnum("routerrpc.FailureDetail", FailureDetail_name, FailureDetail_value)
|
||||
proto.RegisterEnum("routerrpc.PaymentState", PaymentState_name, PaymentState_value)
|
||||
proto.RegisterEnum("routerrpc.ResolveHoldForwardAction", ResolveHoldForwardAction_name, ResolveHoldForwardAction_value)
|
||||
proto.RegisterEnum("routerrpc.ChanStatusAction", ChanStatusAction_name, ChanStatusAction_value)
|
||||
proto.RegisterEnum("routerrpc.HtlcEvent_EventType", HtlcEvent_EventType_name, HtlcEvent_EventType_value)
|
||||
proto.RegisterType((*SendPaymentRequest)(nil), "routerrpc.SendPaymentRequest")
|
||||
proto.RegisterMapType((map[uint64][]byte)(nil), "routerrpc.SendPaymentRequest.DestCustomRecordsEntry")
|
||||
@ -2298,191 +2405,199 @@ func init() {
|
||||
proto.RegisterType((*ForwardHtlcInterceptRequest)(nil), "routerrpc.ForwardHtlcInterceptRequest")
|
||||
proto.RegisterMapType((map[uint64][]byte)(nil), "routerrpc.ForwardHtlcInterceptRequest.CustomRecordsEntry")
|
||||
proto.RegisterType((*ForwardHtlcInterceptResponse)(nil), "routerrpc.ForwardHtlcInterceptResponse")
|
||||
proto.RegisterType((*UpdateChanStatusRequest)(nil), "routerrpc.UpdateChanStatusRequest")
|
||||
proto.RegisterType((*UpdateChanStatusResponse)(nil), "routerrpc.UpdateChanStatusResponse")
|
||||
}
|
||||
|
||||
func init() { proto.RegisterFile("routerrpc/router.proto", fileDescriptor_7a0613f69d37b0a5) }
|
||||
|
||||
var fileDescriptor_7a0613f69d37b0a5 = []byte{
|
||||
// 2854 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x59, 0x4b, 0x77, 0xdb, 0xc6,
|
||||
0x15, 0x0e, 0x48, 0x8a, 0x22, 0x2f, 0x5f, 0xd0, 0x50, 0xb6, 0x58, 0xca, 0x0f, 0x86, 0x79, 0x98,
|
||||
0x75, 0x13, 0xd9, 0x51, 0x7b, 0x92, 0xb4, 0x79, 0x34, 0x14, 0x09, 0x59, 0xb0, 0x29, 0x52, 0x19,
|
||||
0x52, 0x4e, 0x9c, 0x2c, 0xa6, 0x10, 0x39, 0x14, 0x51, 0xe1, 0xc1, 0x02, 0x43, 0xdb, 0xca, 0xaa,
|
||||
0xdd, 0xf5, 0xf4, 0x97, 0x74, 0xd5, 0x5f, 0xd0, 0x73, 0xda, 0x4d, 0x37, 0xfd, 0x13, 0xdd, 0xf6,
|
||||
0x17, 0x74, 0xdd, 0x33, 0x83, 0x01, 0x08, 0x48, 0x94, 0xe4, 0x3e, 0x36, 0x36, 0xf1, 0xdd, 0x6f,
|
||||
0xee, 0xdc, 0xb9, 0x73, 0xef, 0x9d, 0x3b, 0x23, 0xb8, 0xed, 0xb9, 0x0b, 0x46, 0x3d, 0x6f, 0x3e,
|
||||
0x7e, 0x14, 0xfc, 0xda, 0x99, 0x7b, 0x2e, 0x73, 0x51, 0x3e, 0xc2, 0xeb, 0x79, 0x6f, 0x3e, 0x0e,
|
||||
0xd0, 0xe6, 0xdf, 0xd6, 0x01, 0x0d, 0xa9, 0x33, 0x39, 0x32, 0xce, 0x6d, 0xea, 0x30, 0x4c, 0x7f,
|
||||
0xb3, 0xa0, 0x3e, 0x43, 0x08, 0x32, 0x13, 0xea, 0xb3, 0x9a, 0xd2, 0x50, 0x5a, 0x45, 0x2c, 0x7e,
|
||||
0x23, 0x15, 0xd2, 0x86, 0xcd, 0x6a, 0xa9, 0x86, 0xd2, 0x4a, 0x63, 0xfe, 0x13, 0xfd, 0x08, 0x72,
|
||||
0x86, 0xcd, 0x88, 0xed, 0x1b, 0xac, 0x56, 0x14, 0xf0, 0xba, 0x61, 0xb3, 0x43, 0xdf, 0x60, 0xe8,
|
||||
0x6d, 0x28, 0xce, 0x03, 0x95, 0x64, 0x66, 0xf8, 0xb3, 0x5a, 0x5a, 0x28, 0x2a, 0x48, 0xec, 0xc0,
|
||||
0xf0, 0x67, 0xa8, 0x05, 0xea, 0xd4, 0x74, 0x0c, 0x8b, 0x8c, 0x2d, 0xf6, 0x92, 0x4c, 0xa8, 0xc5,
|
||||
0x8c, 0x5a, 0xa6, 0xa1, 0xb4, 0xd6, 0x70, 0x59, 0xe0, 0x1d, 0x8b, 0xbd, 0xec, 0x72, 0x34, 0xae,
|
||||
0xcc, 0x98, 0x4c, 0xbc, 0xda, 0x66, 0x42, 0x59, 0x7b, 0x32, 0xf1, 0xd0, 0x03, 0xa8, 0x84, 0x14,
|
||||
0x2f, 0x58, 0x43, 0x6d, 0xad, 0xa1, 0xb4, 0xf2, 0xb8, 0x3c, 0x4f, 0xae, 0xec, 0x01, 0x54, 0x98,
|
||||
0x69, 0x53, 0x77, 0xc1, 0x88, 0x4f, 0xc7, 0xae, 0x33, 0xf1, 0x6b, 0xd9, 0x60, 0x52, 0x09, 0x0f,
|
||||
0x03, 0x14, 0x35, 0xa1, 0x34, 0xa5, 0x94, 0x58, 0xa6, 0x6d, 0x32, 0xc2, 0x57, 0xb8, 0x2e, 0x56,
|
||||
0x58, 0x98, 0x52, 0xda, 0xe3, 0xd8, 0xd0, 0x60, 0xe8, 0x5d, 0x28, 0x2f, 0x39, 0xc2, 0x0d, 0x25,
|
||||
0x41, 0x2a, 0x86, 0x24, 0xe1, 0x8b, 0x1d, 0x50, 0xdd, 0x05, 0x3b, 0x75, 0x4d, 0xe7, 0x94, 0x8c,
|
||||
0x67, 0x86, 0x43, 0xcc, 0x49, 0x2d, 0xd7, 0x50, 0x5a, 0x99, 0xbd, 0x4c, 0x4d, 0x79, 0xac, 0xe0,
|
||||
0x72, 0x28, 0xed, 0xcc, 0x0c, 0x47, 0x9f, 0xa0, 0x87, 0xb0, 0x71, 0x91, 0xef, 0xd7, 0xaa, 0x8d,
|
||||
0x74, 0x2b, 0x83, 0x2b, 0x49, 0xaa, 0x8f, 0xde, 0x87, 0x8a, 0x65, 0xf8, 0x8c, 0xcc, 0xdc, 0x39,
|
||||
0x99, 0x2f, 0x4e, 0xce, 0xe8, 0x79, 0xad, 0x2c, 0xbc, 0x53, 0xe2, 0xf0, 0x81, 0x3b, 0x3f, 0x12,
|
||||
0x20, 0xba, 0x0b, 0x20, 0xdc, 0x2c, 0x4c, 0xad, 0xe5, 0xc5, 0x8a, 0xf3, 0x1c, 0x11, 0x66, 0xa2,
|
||||
0x8f, 0xa0, 0x20, 0xc2, 0x83, 0xcc, 0x4c, 0x87, 0xf9, 0x35, 0x68, 0xa4, 0x5b, 0x85, 0x5d, 0x75,
|
||||
0xc7, 0x72, 0x78, 0xa4, 0x60, 0x2e, 0x39, 0x30, 0x1d, 0x86, 0xc1, 0x0b, 0x7f, 0xfa, 0x68, 0x02,
|
||||
0x55, 0x1e, 0x16, 0x64, 0xbc, 0xf0, 0x99, 0x6b, 0x13, 0x8f, 0x8e, 0x5d, 0x6f, 0xe2, 0xd7, 0x0a,
|
||||
0x62, 0xe8, 0xcf, 0x76, 0xa2, 0x68, 0xdb, 0xb9, 0x1c, 0x5e, 0x3b, 0x5d, 0xea, 0xb3, 0x8e, 0x18,
|
||||
0x87, 0x83, 0x61, 0x9a, 0xc3, 0xbc, 0x73, 0xbc, 0x31, 0xb9, 0x88, 0xa3, 0x0f, 0x00, 0x19, 0x96,
|
||||
0xe5, 0xbe, 0x22, 0x3e, 0xb5, 0xa6, 0x44, 0xee, 0x65, 0xad, 0xd2, 0x50, 0x5a, 0x39, 0xac, 0x0a,
|
||||
0xc9, 0x90, 0x5a, 0x53, 0xa9, 0x1e, 0x7d, 0x0c, 0x25, 0x61, 0xd3, 0x94, 0x1a, 0x6c, 0xe1, 0x51,
|
||||
0xbf, 0xa6, 0x36, 0xd2, 0xad, 0xf2, 0xee, 0x86, 0x5c, 0xc8, 0x7e, 0x00, 0xef, 0x99, 0x0c, 0x17,
|
||||
0x39, 0x4f, 0x7e, 0xfb, 0x68, 0x1b, 0xf2, 0xb6, 0xf1, 0x9a, 0xcc, 0x0d, 0x8f, 0xf9, 0xb5, 0x8d,
|
||||
0x86, 0xd2, 0x2a, 0xe1, 0x9c, 0x6d, 0xbc, 0x3e, 0xe2, 0xdf, 0x68, 0x07, 0xaa, 0x8e, 0x4b, 0x4c,
|
||||
0x67, 0x6a, 0x99, 0xa7, 0x33, 0x46, 0x16, 0xf3, 0x89, 0xc1, 0xa8, 0x5f, 0x43, 0xc2, 0x86, 0x0d,
|
||||
0xc7, 0xd5, 0xa5, 0xe4, 0x38, 0x10, 0xa0, 0x0f, 0xa1, 0xca, 0x95, 0xf9, 0x33, 0xc3, 0x9b, 0x10,
|
||||
0xdf, 0xfc, 0x81, 0x06, 0x91, 0x71, 0x8b, 0xef, 0x38, 0x56, 0x6d, 0xe3, 0xf5, 0x90, 0x4b, 0x86,
|
||||
0xe6, 0x0f, 0x94, 0x47, 0x47, 0xbd, 0x0b, 0xb7, 0x57, 0xbb, 0x83, 0x27, 0x1c, 0xdf, 0x4f, 0x45,
|
||||
0x0c, 0xe4, 0x3f, 0xd1, 0x26, 0xac, 0xbd, 0x34, 0xac, 0x05, 0x15, 0x49, 0x58, 0xc4, 0xc1, 0xc7,
|
||||
0x2f, 0x52, 0x9f, 0x2a, 0xcd, 0x19, 0x54, 0x47, 0x9e, 0x31, 0x3e, 0xbb, 0x90, 0xc7, 0x17, 0xd3,
|
||||
0x50, 0xb9, 0x9c, 0x86, 0x57, 0x2c, 0x2f, 0x75, 0xc5, 0xf2, 0x9a, 0x5f, 0x42, 0x45, 0x04, 0xc4,
|
||||
0x3e, 0xa5, 0xd7, 0x55, 0x8b, 0x2d, 0xe0, 0xb5, 0x40, 0x24, 0x4e, 0x50, 0x31, 0xb2, 0x86, 0xcd,
|
||||
0x73, 0xa6, 0x39, 0x01, 0x75, 0x39, 0xde, 0x9f, 0xbb, 0x8e, 0x4f, 0x79, 0x29, 0xe0, 0xf1, 0xc2,
|
||||
0x03, 0x9e, 0xe7, 0x93, 0xf0, 0x97, 0x22, 0x46, 0x95, 0x25, 0xbe, 0x4f, 0x85, 0xb7, 0x78, 0xbc,
|
||||
0xf3, 0x3c, 0x25, 0x96, 0x3b, 0x3e, 0xe3, 0x35, 0xc3, 0x38, 0x97, 0xea, 0x4b, 0x1c, 0xee, 0xb9,
|
||||
0xe3, 0xb3, 0x2e, 0x07, 0x9b, 0xdf, 0x07, 0x65, 0x6d, 0xe4, 0x8a, 0xb9, 0xfe, 0x03, 0x77, 0x34,
|
||||
0x61, 0x4d, 0x84, 0xae, 0x50, 0x5b, 0xd8, 0x2d, 0xc6, 0x73, 0x00, 0x07, 0xa2, 0xe6, 0xf7, 0x50,
|
||||
0x4d, 0x28, 0x97, 0xab, 0xa8, 0x43, 0x6e, 0xee, 0x51, 0xd3, 0x36, 0x4e, 0xa9, 0xd4, 0x1c, 0x7d,
|
||||
0xa3, 0x16, 0xac, 0x4f, 0x0d, 0xd3, 0x5a, 0x78, 0xa1, 0xe2, 0x72, 0x18, 0x93, 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, 0x7a, 0x41,
|
||||
0xbd, 0xf3, 0xd5, 0x83, 0xbf, 0x86, 0xed, 0x95, 0x52, 0x69, 0xff, 0x07, 0xb0, 0x36, 0x37, 0x4c,
|
||||
0x8f, 0xef, 0x3d, 0xcf, 0xe1, 0xdb, 0xb1, 0x1c, 0x3e, 0x32, 0x4c, 0xef, 0xc0, 0xf4, 0x99, 0xeb,
|
||||
0x9d, 0xe3, 0x80, 0xf4, 0x34, 0x93, 0x53, 0xd4, 0x54, 0xf3, 0x0f, 0x0a, 0x14, 0x62, 0x42, 0x9e,
|
||||
0x49, 0x8e, 0x3b, 0xa1, 0x64, 0xea, 0xb9, 0x76, 0xe8, 0x04, 0x0e, 0xec, 0x7b, 0xae, 0xcd, 0x63,
|
||||
0x42, 0x08, 0x99, 0x2b, 0x03, 0x38, 0xcb, 0x3f, 0x47, 0x2e, 0xfa, 0x10, 0xd6, 0x67, 0x81, 0x02,
|
||||
0x51, 0x65, 0x0b, 0xbb, 0xd5, 0x0b, 0x73, 0x77, 0x0d, 0x66, 0xe0, 0x90, 0xf3, 0x34, 0x93, 0x4b,
|
||||
0xab, 0x99, 0xa7, 0x99, 0x5c, 0x46, 0x5d, 0x7b, 0x9a, 0xc9, 0xad, 0xa9, 0xd9, 0xa7, 0x99, 0x5c,
|
||||
0x56, 0x5d, 0x6f, 0xfe, 0x53, 0x81, 0x5c, 0xc8, 0xe6, 0x96, 0x70, 0x97, 0x12, 0x1e, 0x17, 0x32,
|
||||
0x98, 0x72, 0x1c, 0x18, 0x99, 0x36, 0x45, 0x0d, 0x28, 0x0a, 0x61, 0x32, 0x44, 0x81, 0x63, 0x6d,
|
||||
0x11, 0xa6, 0xa2, 0xfc, 0x87, 0x0c, 0x11, 0x8f, 0x19, 0x59, 0xfe, 0x03, 0x4a, 0x78, 0xc8, 0xf9,
|
||||
0x8b, 0xf1, 0x98, 0xfa, 0x7e, 0x30, 0xcb, 0x5a, 0x40, 0x91, 0x98, 0x98, 0xe8, 0x7d, 0xa8, 0x84,
|
||||
0x94, 0x70, 0xae, 0x6c, 0x10, 0xaf, 0x12, 0x96, 0xd3, 0xb5, 0x40, 0x8d, 0xf3, 0xec, 0xe5, 0x81,
|
||||
0x53, 0x5e, 0x12, 0xf9, 0xa4, 0xc1, 0xe2, 0x9b, 0x0d, 0xb8, 0xf7, 0xe4, 0x62, 0x14, 0x74, 0x5c,
|
||||
0x67, 0x6a, 0x9e, 0x86, 0x9b, 0xfd, 0x1d, 0xdc, 0xbf, 0x92, 0x21, 0x37, 0xfc, 0x13, 0xc8, 0x8e,
|
||||
0x05, 0x22, 0xfc, 0x53, 0xd8, 0xbd, 0x1f, 0xf3, 0xfa, 0xca, 0x81, 0x92, 0xde, 0x7c, 0x01, 0xf7,
|
||||
0x86, 0xd7, 0xce, 0xfe, 0xdf, 0xab, 0x7e, 0x1b, 0xee, 0x0f, 0xaf, 0x37, 0xbb, 0xf9, 0xdb, 0x14,
|
||||
0x6c, 0xae, 0x22, 0xf0, 0x83, 0x73, 0x66, 0x58, 0x53, 0x62, 0x99, 0x53, 0x1a, 0x9d, 0xee, 0x41,
|
||||
0xf9, 0xac, 0x70, 0x41, 0xcf, 0x9c, 0xd2, 0xf0, 0x78, 0x7f, 0x00, 0x15, 0x71, 0x66, 0x7a, 0xee,
|
||||
0x89, 0x71, 0x62, 0x5a, 0x26, 0x0b, 0x0a, 0x49, 0x0a, 0x97, 0x67, 0xee, 0xfc, 0x68, 0x89, 0xa2,
|
||||
0xdb, 0x90, 0x7d, 0x45, 0x79, 0x01, 0x14, 0x3d, 0x4c, 0x0a, 0xcb, 0x2f, 0xf4, 0x31, 0x6c, 0xd9,
|
||||
0xc6, 0x6b, 0xd3, 0x5e, 0xd8, 0x64, 0xd9, 0x79, 0xf8, 0x0b, 0x8b, 0xf9, 0x22, 0x54, 0x4a, 0xf8,
|
||||
0x96, 0x14, 0x47, 0x25, 0x59, 0x08, 0x51, 0x07, 0xee, 0xd9, 0xa6, 0x23, 0xc6, 0xc9, 0x94, 0x27,
|
||||
0x1e, 0xb5, 0x8c, 0xd7, 0xc4, 0x74, 0x18, 0xf5, 0x5e, 0x1a, 0x96, 0x08, 0xa3, 0x0c, 0xde, 0x96,
|
||||
0xac, 0xb0, 0x40, 0x70, 0x8e, 0x2e, 0x29, 0xcd, 0x5f, 0xc3, 0x96, 0xc8, 0xe4, 0x98, 0xa1, 0xa1,
|
||||
0xe7, 0x79, 0xdc, 0x7b, 0xae, 0x4d, 0x78, 0x6a, 0x85, 0x19, 0xc8, 0x81, 0xbe, 0x3b, 0xa1, 0x3c,
|
||||
0x03, 0x99, 0x1b, 0x88, 0x64, 0x06, 0x32, 0x57, 0x08, 0xe2, 0xad, 0x5c, 0x3a, 0xd1, 0xca, 0x35,
|
||||
0xcf, 0xa0, 0x76, 0x79, 0x2e, 0x19, 0x41, 0x0d, 0x28, 0xc4, 0x3d, 0xc8, 0xa7, 0x53, 0x70, 0x1c,
|
||||
0x8a, 0xa7, 0x76, 0xea, 0xe6, 0xd4, 0x6e, 0xfe, 0x5d, 0x81, 0x8d, 0xbd, 0x85, 0x69, 0x4d, 0x12,
|
||||
0x75, 0x3b, 0x6e, 0x9d, 0x92, 0x6c, 0x34, 0x57, 0x75, 0x91, 0xa9, 0x95, 0x5d, 0xe4, 0x07, 0x2b,
|
||||
0xda, 0xb0, 0xb4, 0x68, 0xc3, 0x52, 0x2b, 0x9a, 0xb0, 0xfb, 0x50, 0x58, 0xf6, 0x54, 0x7c, 0x4b,
|
||||
0xd3, 0xad, 0x22, 0x86, 0x59, 0xd8, 0x50, 0xf9, 0x97, 0x9a, 0xd2, 0xb5, 0x4b, 0x4d, 0x69, 0xf3,
|
||||
0x53, 0x40, 0xf1, 0xb5, 0x48, 0x9f, 0x45, 0x27, 0x8c, 0x72, 0xf5, 0x09, 0x73, 0x07, 0xea, 0xc3,
|
||||
0xc5, 0x89, 0x3f, 0xf6, 0xcc, 0x13, 0x7a, 0xc0, 0xac, 0xb1, 0xf6, 0x92, 0x3a, 0xcc, 0x0f, 0x53,
|
||||
0xfb, 0x5f, 0x19, 0xc8, 0x47, 0x28, 0x3f, 0xc0, 0x4d, 0x67, 0xec, 0xda, 0xe1, 0xba, 0x1c, 0x6a,
|
||||
0xf1, 0xa5, 0x05, 0x71, 0xbf, 0x11, 0x8a, 0x3a, 0x81, 0x44, 0x9f, 0x70, 0x7e, 0xc2, 0x0f, 0x92,
|
||||
0x9f, 0x0a, 0xf8, 0x71, 0x37, 0x04, 0xfc, 0x16, 0xa8, 0x91, 0xfe, 0x19, 0xb3, 0xc6, 0x91, 0xdf,
|
||||
0x70, 0x39, 0xc4, 0xb9, 0x31, 0x01, 0x33, 0xd2, 0x1c, 0x32, 0x33, 0x01, 0x33, 0xc4, 0x25, 0xf3,
|
||||
0x6d, 0x28, 0xf2, 0x8a, 0xe9, 0x33, 0xc3, 0x9e, 0x13, 0xc7, 0x97, 0x21, 0x5f, 0x88, 0xb0, 0xbe,
|
||||
0x8f, 0xbe, 0x00, 0xa0, 0x7c, 0x7d, 0x84, 0x9d, 0xcf, 0xa9, 0x28, 0x9a, 0xe5, 0xdd, 0x7b, 0xb1,
|
||||
0xd8, 0x89, 0x1c, 0xb0, 0x23, 0xfe, 0x1d, 0x9d, 0xcf, 0x29, 0xce, 0xd3, 0xf0, 0x27, 0xfa, 0x12,
|
||||
0x4a, 0x53, 0xd7, 0x7b, 0xc5, 0x7b, 0x30, 0x01, 0xca, 0x83, 0x65, 0x2b, 0xa6, 0x61, 0x3f, 0x90,
|
||||
0x8b, 0xe1, 0x07, 0x6f, 0xe1, 0xe2, 0x34, 0xf6, 0x8d, 0x9e, 0x01, 0x0a, 0xc7, 0x8b, 0x73, 0x20,
|
||||
0x50, 0x92, 0x13, 0x4a, 0xb6, 0x2f, 0x2b, 0xe1, 0x59, 0x1a, 0x2a, 0x52, 0xa7, 0x17, 0x30, 0xf4,
|
||||
0x19, 0x14, 0x7d, 0xca, 0x98, 0x45, 0xa5, 0x9a, 0xbc, 0x50, 0x73, 0x3b, 0xd1, 0x24, 0x73, 0x71,
|
||||
0xa8, 0xa1, 0xe0, 0x2f, 0x3f, 0xd1, 0x1e, 0x54, 0x2c, 0xd3, 0x39, 0x8b, 0x9b, 0x01, 0x62, 0x7c,
|
||||
0x2d, 0x36, 0xbe, 0x67, 0x3a, 0x67, 0x71, 0x1b, 0x4a, 0x56, 0x1c, 0x68, 0x7e, 0x0e, 0xf9, 0xc8,
|
||||
0x4b, 0xa8, 0x00, 0xeb, 0xc7, 0xfd, 0x67, 0xfd, 0xc1, 0x37, 0x7d, 0xf5, 0x2d, 0x94, 0x83, 0xcc,
|
||||
0x50, 0xeb, 0x77, 0x55, 0x85, 0xc3, 0x58, 0xeb, 0x68, 0xfa, 0x73, 0x4d, 0x4d, 0xf1, 0x8f, 0xfd,
|
||||
0x01, 0xfe, 0xa6, 0x8d, 0xbb, 0x6a, 0x7a, 0x6f, 0x1d, 0xd6, 0xc4, 0xbc, 0xcd, 0x3f, 0x2b, 0x90,
|
||||
0x13, 0x3b, 0xe8, 0x4c, 0x5d, 0xf4, 0x13, 0x88, 0x82, 0x4b, 0x1c, 0x7f, 0xbc, 0x25, 0x13, 0x51,
|
||||
0x57, 0xc2, 0x51, 0xc0, 0x8c, 0x24, 0xce, 0xc9, 0x51, 0x68, 0x44, 0xe4, 0x54, 0x40, 0x0e, 0x05,
|
||||
0x11, 0xf9, 0x61, 0x4c, 0x73, 0xa2, 0x2a, 0x65, 0x70, 0x25, 0x14, 0x84, 0x67, 0x70, 0xfc, 0xb2,
|
||||
0x94, 0x38, 0xab, 0x63, 0x97, 0x25, 0xc9, 0x6d, 0x7e, 0x02, 0xc5, 0xf8, 0x9e, 0xa3, 0x07, 0x90,
|
||||
0x31, 0x9d, 0xa9, 0x2b, 0x13, 0xb1, 0x7a, 0x21, 0xb8, 0xf8, 0x22, 0xb1, 0x20, 0x34, 0x11, 0xa8,
|
||||
0x17, 0xf7, 0xb9, 0x59, 0x82, 0x42, 0x6c, 0xd3, 0x9a, 0xff, 0x50, 0xa0, 0x94, 0xd8, 0x84, 0x37,
|
||||
0xd6, 0x8e, 0xbe, 0x80, 0xe2, 0x2b, 0xd3, 0xa3, 0x24, 0xde, 0x20, 0x96, 0x77, 0xeb, 0xc9, 0x06,
|
||||
0x31, 0xfc, 0xbf, 0xe3, 0x4e, 0x28, 0x2e, 0x70, 0xbe, 0x04, 0xd0, 0x2f, 0xa1, 0x1c, 0x1e, 0x24,
|
||||
0x13, 0xca, 0x0c, 0xd3, 0x12, 0xae, 0x2a, 0x27, 0xc2, 0x43, 0x72, 0xbb, 0x42, 0x8e, 0x4b, 0xd3,
|
||||
0xf8, 0x27, 0x7a, 0x6f, 0xa9, 0xc0, 0x67, 0x9e, 0xe9, 0x9c, 0x0a, 0xff, 0xe5, 0x23, 0xda, 0x50,
|
||||
0x80, 0xbc, 0xd5, 0x2b, 0xc9, 0xb3, 0x6c, 0xc8, 0x0c, 0xb6, 0xe0, 0x37, 0x9d, 0x35, 0x9f, 0x19,
|
||||
0xb2, 0x92, 0x95, 0x13, 0xb9, 0x15, 0x23, 0x52, 0x1c, 0xb0, 0x12, 0xfd, 0x71, 0xea, 0x52, 0x7f,
|
||||
0xbc, 0xc6, 0x2b, 0x46, 0x50, 0x68, 0x0b, 0xbb, 0x48, 0x2e, 0xfe, 0x60, 0xd4, 0xeb, 0xb4, 0x19,
|
||||
0xa3, 0xf6, 0x9c, 0xe1, 0x80, 0x20, 0xfb, 0x9f, 0x2f, 0x01, 0x3a, 0xa6, 0x37, 0x5e, 0x98, 0xec,
|
||||
0x19, 0x3d, 0xe7, 0xc7, 0x5a, 0x58, 0xd1, 0x83, 0xb2, 0x97, 0x1d, 0x07, 0x55, 0x7c, 0x0b, 0xd6,
|
||||
0xc3, 0x42, 0x14, 0xd4, 0xb7, 0xec, 0x4c, 0x14, 0xa0, 0xe6, 0x5f, 0x32, 0xb0, 0x2d, 0xb7, 0x34,
|
||||
0xd8, 0x0d, 0x46, 0xbd, 0x31, 0x9d, 0x47, 0x17, 0xa7, 0x27, 0xb0, 0xb9, 0x2c, 0xaa, 0xc1, 0x44,
|
||||
0x24, 0xbc, 0x8c, 0x15, 0x76, 0x6f, 0xc5, 0x56, 0xba, 0x34, 0x03, 0xa3, 0xa8, 0xd8, 0x2e, 0x4d,
|
||||
0x7b, 0x1c, 0x53, 0x64, 0xd8, 0xee, 0xc2, 0x91, 0x21, 0x1a, 0x54, 0x3c, 0xb4, 0x0c, 0x67, 0x2e,
|
||||
0x12, 0x11, 0xfd, 0x00, 0xa2, 0x20, 0x27, 0xf4, 0xf5, 0xdc, 0xf4, 0xce, 0x45, 0xf5, 0x2b, 0x2d,
|
||||
0xcb, 0xad, 0x26, 0xd0, 0x4b, 0xb7, 0x99, 0xd4, 0xe5, 0xdb, 0xcc, 0x67, 0x50, 0x8f, 0xb2, 0x43,
|
||||
0xbe, 0x8b, 0xd0, 0x49, 0x74, 0xfa, 0xad, 0x0b, 0x1b, 0xb6, 0x42, 0x06, 0x0e, 0x09, 0xf2, 0x08,
|
||||
0x7c, 0x0c, 0x9b, 0xb1, 0xd4, 0x5a, 0x9a, 0x1e, 0x64, 0x22, 0x5a, 0x66, 0x57, 0xdc, 0xf4, 0x68,
|
||||
0x84, 0x34, 0x3d, 0xe8, 0x85, 0xa2, 0xfa, 0x2f, 0x4d, 0xff, 0x15, 0x94, 0x2f, 0xbc, 0x1b, 0xe4,
|
||||
0xc4, 0xbe, 0xff, 0xfc, 0x72, 0x65, 0x5d, 0xb5, 0x3d, 0x3b, 0x2b, 0x1e, 0x0f, 0x4a, 0xe3, 0xc4,
|
||||
0xc3, 0xc1, 0x5d, 0x00, 0xd7, 0x31, 0x5d, 0x87, 0x9c, 0x58, 0xee, 0x89, 0x28, 0xb8, 0x45, 0x9c,
|
||||
0x17, 0xc8, 0x9e, 0xe5, 0x9e, 0xd4, 0xbf, 0x02, 0xf4, 0x3f, 0xde, 0xb8, 0xff, 0xaa, 0xc0, 0x9d,
|
||||
0xd5, 0x26, 0xca, 0x73, 0xfe, 0xff, 0x16, 0x42, 0x9f, 0x41, 0xd6, 0x18, 0x33, 0xd3, 0x75, 0x64,
|
||||
0x65, 0x78, 0x27, 0x36, 0x14, 0x53, 0xdf, 0xb5, 0x5e, 0xd2, 0x03, 0xd7, 0x9a, 0x48, 0x63, 0xda,
|
||||
0x82, 0x8a, 0xe5, 0x90, 0x44, 0xd2, 0xa5, 0x93, 0x49, 0xf7, 0xf0, 0x77, 0x19, 0x28, 0x25, 0x2a,
|
||||
0x43, 0xf2, 0x68, 0x28, 0x41, 0xbe, 0x3f, 0x20, 0x5d, 0x6d, 0xd4, 0xd6, 0x7b, 0xaa, 0x82, 0x54,
|
||||
0x28, 0x0e, 0xfa, 0xfa, 0xa0, 0x4f, 0xba, 0x5a, 0x67, 0xd0, 0xe5, 0x87, 0xc4, 0x2d, 0xd8, 0xe8,
|
||||
0xe9, 0xfd, 0x67, 0xa4, 0x3f, 0x18, 0x11, 0xad, 0xa7, 0x3f, 0xd1, 0xf7, 0x7a, 0x9a, 0x9a, 0x46,
|
||||
0x9b, 0xa0, 0x0e, 0xfa, 0xa4, 0x73, 0xd0, 0xd6, 0xfb, 0x64, 0xa4, 0x1f, 0x6a, 0x83, 0xe3, 0x91,
|
||||
0x9a, 0xe1, 0x28, 0xcf, 0x66, 0xa2, 0x7d, 0xdb, 0xd1, 0xb4, 0xee, 0x90, 0x1c, 0xb6, 0xbf, 0x55,
|
||||
0xd7, 0x50, 0x0d, 0x36, 0xf5, 0xfe, 0xf0, 0x78, 0x7f, 0x5f, 0xef, 0xe8, 0x5a, 0x7f, 0x44, 0xf6,
|
||||
0xda, 0xbd, 0x76, 0xbf, 0xa3, 0xa9, 0x59, 0x74, 0x1b, 0x90, 0xde, 0xef, 0x0c, 0x0e, 0x8f, 0x7a,
|
||||
0xda, 0x48, 0x23, 0xe1, 0x61, 0xb4, 0x8e, 0xaa, 0x50, 0x11, 0x7a, 0xda, 0xdd, 0x2e, 0xd9, 0x6f,
|
||||
0xeb, 0x3d, 0xad, 0xab, 0xe6, 0xb8, 0x25, 0x92, 0x31, 0x24, 0x5d, 0x7d, 0xd8, 0xde, 0xe3, 0x70,
|
||||
0x9e, 0xcf, 0xa9, 0xf7, 0x9f, 0x0f, 0xf4, 0x8e, 0x46, 0x3a, 0x5c, 0x2d, 0x47, 0x81, 0x93, 0x43,
|
||||
0xf4, 0xb8, 0xdf, 0xd5, 0xf0, 0x51, 0x5b, 0xef, 0xaa, 0x05, 0xb4, 0x0d, 0x5b, 0x21, 0xac, 0x7d,
|
||||
0x7b, 0xa4, 0xe3, 0x17, 0x64, 0x34, 0x18, 0x90, 0xe1, 0x60, 0xd0, 0x57, 0x8b, 0x71, 0x4d, 0x7c,
|
||||
0xb5, 0x83, 0x23, 0xad, 0xaf, 0x96, 0xd0, 0x16, 0x54, 0x0f, 0x8f, 0x8e, 0x48, 0x28, 0x09, 0x17,
|
||||
0x5b, 0xe6, 0xf4, 0x76, 0xb7, 0x8b, 0xb5, 0xe1, 0x90, 0x1c, 0xea, 0xc3, 0xc3, 0xf6, 0xa8, 0x73,
|
||||
0xa0, 0x56, 0xf8, 0x92, 0x86, 0xda, 0x88, 0x8c, 0x06, 0xa3, 0x76, 0x6f, 0x89, 0xab, 0xdc, 0xa0,
|
||||
0x25, 0xce, 0x27, 0xed, 0x0d, 0xbe, 0x51, 0x37, 0xb8, 0xc3, 0x39, 0x3c, 0x78, 0x2e, 0x4d, 0x44,
|
||||
0x7c, 0xed, 0x72, 0x7b, 0xc2, 0x39, 0xd5, 0x2a, 0x07, 0xf5, 0xfe, 0xf3, 0x76, 0x4f, 0xef, 0x92,
|
||||
0x67, 0xda, 0x0b, 0x71, 0x98, 0x6f, 0x72, 0x30, 0xb0, 0x8c, 0x1c, 0xe1, 0xc1, 0x13, 0x6e, 0x88,
|
||||
0x7a, 0x0b, 0x21, 0x28, 0x77, 0x74, 0xdc, 0x39, 0xee, 0xb5, 0x31, 0xc1, 0x83, 0xe3, 0x91, 0xa6,
|
||||
0xde, 0x7e, 0xf8, 0x27, 0x05, 0x8a, 0xf1, 0x62, 0xcd, 0x77, 0x5d, 0xef, 0x93, 0xfd, 0x9e, 0xfe,
|
||||
0xe4, 0x60, 0x14, 0x04, 0xc1, 0xf0, 0xb8, 0xc3, 0xb7, 0x4c, 0xe3, 0x4d, 0x02, 0x82, 0x72, 0xe0,
|
||||
0xf4, 0x68, 0xb1, 0x29, 0x3e, 0x97, 0xc4, 0xfa, 0x03, 0xa9, 0x37, 0xcd, 0x8d, 0x97, 0xa0, 0x86,
|
||||
0xf1, 0x00, 0xab, 0x19, 0xf4, 0x2e, 0x34, 0x24, 0xc2, 0xf7, 0x15, 0x63, 0xad, 0x33, 0x22, 0x47,
|
||||
0xed, 0x17, 0x87, 0x7c, 0xdb, 0x83, 0x20, 0x1b, 0xaa, 0x6b, 0xe8, 0x3e, 0x6c, 0x47, 0xac, 0x55,
|
||||
0x71, 0xf1, 0xf0, 0x73, 0xa8, 0x5d, 0x15, 0xf4, 0x08, 0x20, 0x3b, 0xd4, 0x46, 0xa3, 0x9e, 0x16,
|
||||
0x34, 0x36, 0xfb, 0x41, 0xe0, 0x02, 0x64, 0xb1, 0x36, 0x3c, 0x3e, 0xd4, 0xd4, 0xd4, 0xee, 0x1f,
|
||||
0xf9, 0x87, 0xc8, 0x1e, 0xf4, 0x15, 0x94, 0x62, 0x4f, 0x93, 0xcf, 0x77, 0xd1, 0xdd, 0x6b, 0x1f,
|
||||
0x2d, 0xeb, 0xe1, 0x8b, 0x8d, 0x84, 0x1f, 0x2b, 0x68, 0x0f, 0xca, 0xf1, 0x47, 0xb7, 0xe7, 0xbb,
|
||||
0x28, 0xde, 0xa0, 0xae, 0x78, 0x8f, 0x5b, 0xa1, 0xe3, 0x19, 0xa8, 0x9a, 0xcf, 0x4c, 0x9b, 0x9f,
|
||||
0x93, 0xf2, 0x59, 0x0c, 0xd5, 0xe3, 0x09, 0x9e, 0x7c, 0x6b, 0xab, 0x6f, 0xaf, 0x94, 0xc9, 0x92,
|
||||
0xf3, 0x35, 0xef, 0x49, 0xa2, 0x87, 0xa9, 0x4b, 0x0b, 0x4a, 0xbe, 0x86, 0xd5, 0xef, 0x5d, 0x25,
|
||||
0x96, 0xf7, 0xec, 0xf4, 0xef, 0x53, 0x7c, 0x8d, 0xa5, 0x98, 0x6c, 0x85, 0x97, 0x2e, 0x28, 0x5d,
|
||||
0x71, 0x72, 0xa3, 0x09, 0x54, 0x57, 0x3c, 0x5a, 0xa1, 0xf7, 0x92, 0x75, 0xec, 0x8a, 0x27, 0xaf,
|
||||
0xfa, 0xfb, 0x37, 0xd1, 0xe4, 0xe2, 0x27, 0x50, 0x5d, 0xf1, 0xba, 0x95, 0x98, 0xe5, 0xea, 0xb7,
|
||||
0xb1, 0xc4, 0x2c, 0xd7, 0x3d, 0x92, 0xcd, 0x61, 0xeb, 0x8a, 0x67, 0x15, 0xf4, 0xe3, 0x98, 0x8a,
|
||||
0xeb, 0x1f, 0x67, 0xea, 0x0f, 0xdf, 0x84, 0xba, 0x9c, 0x71, 0xf8, 0x06, 0x33, 0x0e, 0xdf, 0x7c,
|
||||
0xc6, 0x1b, 0x1e, 0x58, 0xd0, 0xf7, 0xa0, 0x5e, 0xbc, 0xf1, 0xa3, 0xe6, 0x45, 0xff, 0x5c, 0x7e,
|
||||
0x7a, 0xa8, 0xbf, 0x73, 0x2d, 0x47, 0x2a, 0xd7, 0x01, 0x96, 0x97, 0x62, 0x74, 0x27, 0x36, 0xe4,
|
||||
0xd2, 0xbd, 0xbf, 0x7e, 0xf7, 0x0a, 0xa9, 0x54, 0x35, 0x82, 0xea, 0x8a, 0x5b, 0x72, 0x62, 0xc7,
|
||||
0xaf, 0xbe, 0x45, 0xd7, 0x37, 0x57, 0x5d, 0x26, 0x1f, 0x2b, 0xe8, 0x30, 0x48, 0xa2, 0xf0, 0x6f,
|
||||
0x0a, 0x37, 0x54, 0x85, 0xda, 0xea, 0xa6, 0x77, 0xe1, 0x8b, 0xf4, 0x79, 0xac, 0xa0, 0x01, 0x14,
|
||||
0xe3, 0x95, 0xe0, 0xc6, 0x12, 0x71, 0xa3, 0xc2, 0x29, 0x54, 0x12, 0x0d, 0x87, 0xeb, 0xa1, 0x07,
|
||||
0x37, 0xb6, 0x4d, 0x81, 0xc7, 0x12, 0x51, 0x7e, 0x4d, 0x7f, 0xd5, 0x52, 0x1e, 0x2b, 0x7b, 0x1f,
|
||||
0x7d, 0xf7, 0xe8, 0xd4, 0x64, 0xb3, 0xc5, 0xc9, 0xce, 0xd8, 0xb5, 0x1f, 0x89, 0xbf, 0x01, 0x38,
|
||||
0xa6, 0x73, 0xea, 0x50, 0xf6, 0xca, 0xf5, 0xce, 0x1e, 0x59, 0xce, 0xe4, 0x91, 0x48, 0xf5, 0x47,
|
||||
0x91, 0xca, 0x93, 0xac, 0xf8, 0xa3, 0xe2, 0x4f, 0xff, 0x1d, 0x00, 0x00, 0xff, 0xff, 0xa0, 0xe5,
|
||||
0x92, 0xf0, 0x84, 0x1c, 0x00, 0x00,
|
||||
// 2955 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x59, 0x5b, 0x77, 0xdb, 0xc6,
|
||||
0xf1, 0x0f, 0x48, 0x8a, 0x22, 0x87, 0x17, 0x41, 0x2b, 0xd9, 0xe2, 0x9f, 0xf2, 0x45, 0x61, 0x2e,
|
||||
0xe6, 0xdf, 0x4d, 0x64, 0x47, 0x69, 0x93, 0xb4, 0xb9, 0x34, 0x14, 0x09, 0x59, 0xb0, 0x29, 0x52,
|
||||
0x59, 0x52, 0x4e, 0x1c, 0x3f, 0x6c, 0x21, 0x72, 0x29, 0xa2, 0x02, 0x01, 0x16, 0x58, 0xda, 0x56,
|
||||
0x9e, 0xda, 0x9e, 0xd3, 0x73, 0x7a, 0xfa, 0x61, 0xfa, 0x09, 0x7a, 0x4e, 0xfb, 0xd2, 0x97, 0x7e,
|
||||
0x89, 0xbe, 0xf6, 0x13, 0xf4, 0xb9, 0x67, 0x2f, 0x00, 0x01, 0x8a, 0x92, 0xdd, 0xcb, 0x8b, 0x4d,
|
||||
0xfc, 0xe6, 0xb7, 0xb3, 0xb3, 0xb3, 0x33, 0xb3, 0xb3, 0x2b, 0xb8, 0xe9, 0x7b, 0x33, 0x46, 0x7d,
|
||||
0x7f, 0x3a, 0x78, 0x20, 0x7f, 0xed, 0x4e, 0x7d, 0x8f, 0x79, 0x28, 0x1f, 0xe1, 0xd5, 0xbc, 0x3f,
|
||||
0x1d, 0x48, 0xb4, 0xf6, 0xd7, 0x55, 0x40, 0x3d, 0xea, 0x0e, 0x8f, 0xad, 0x8b, 0x09, 0x75, 0x19,
|
||||
0xa6, 0xbf, 0x9a, 0xd1, 0x80, 0x21, 0x04, 0x99, 0x21, 0x0d, 0x58, 0x45, 0xdb, 0xd1, 0xea, 0x45,
|
||||
0x2c, 0x7e, 0x23, 0x1d, 0xd2, 0xd6, 0x84, 0x55, 0x52, 0x3b, 0x5a, 0x3d, 0x8d, 0xf9, 0x4f, 0xf4,
|
||||
0x7f, 0x90, 0xb3, 0x26, 0x8c, 0x4c, 0x02, 0x8b, 0x55, 0x8a, 0x02, 0x5e, 0xb5, 0x26, 0xec, 0x28,
|
||||
0xb0, 0x18, 0x7a, 0x1b, 0x8a, 0x53, 0xa9, 0x92, 0x8c, 0xad, 0x60, 0x5c, 0x49, 0x0b, 0x45, 0x05,
|
||||
0x85, 0x1d, 0x5a, 0xc1, 0x18, 0xd5, 0x41, 0x1f, 0xd9, 0xae, 0xe5, 0x90, 0x81, 0xc3, 0x5e, 0x90,
|
||||
0x21, 0x75, 0x98, 0x55, 0xc9, 0xec, 0x68, 0xf5, 0x15, 0x5c, 0x16, 0x78, 0xd3, 0x61, 0x2f, 0x5a,
|
||||
0x1c, 0x8d, 0x2b, 0xb3, 0x86, 0x43, 0xbf, 0xb2, 0x99, 0x50, 0xd6, 0x18, 0x0e, 0x7d, 0x74, 0x0f,
|
||||
0xd6, 0x42, 0x8a, 0x2f, 0xd7, 0x50, 0x59, 0xd9, 0xd1, 0xea, 0x79, 0x5c, 0x9e, 0x26, 0x57, 0x76,
|
||||
0x0f, 0xd6, 0x98, 0x3d, 0xa1, 0xde, 0x8c, 0x91, 0x80, 0x0e, 0x3c, 0x77, 0x18, 0x54, 0xb2, 0x72,
|
||||
0x52, 0x05, 0xf7, 0x24, 0x8a, 0x6a, 0x50, 0x1a, 0x51, 0x4a, 0x1c, 0x7b, 0x62, 0x33, 0xc2, 0x57,
|
||||
0xb8, 0x2a, 0x56, 0x58, 0x18, 0x51, 0xda, 0xe6, 0x58, 0xcf, 0x62, 0xe8, 0x5d, 0x28, 0xcf, 0x39,
|
||||
0xc2, 0x0d, 0x25, 0x41, 0x2a, 0x86, 0x24, 0xe1, 0x8b, 0x5d, 0xd0, 0xbd, 0x19, 0x3b, 0xf3, 0x6c,
|
||||
0xf7, 0x8c, 0x0c, 0xc6, 0x96, 0x4b, 0xec, 0x61, 0x25, 0xb7, 0xa3, 0xd5, 0x33, 0xfb, 0x99, 0x8a,
|
||||
0xf6, 0x50, 0xc3, 0xe5, 0x50, 0xda, 0x1c, 0x5b, 0xae, 0x39, 0x44, 0xf7, 0x61, 0x7d, 0x91, 0x1f,
|
||||
0x54, 0x36, 0x76, 0xd2, 0xf5, 0x0c, 0x5e, 0x4b, 0x52, 0x03, 0xf4, 0x3e, 0xac, 0x39, 0x56, 0xc0,
|
||||
0xc8, 0xd8, 0x9b, 0x92, 0xe9, 0xec, 0xf4, 0x9c, 0x5e, 0x54, 0xca, 0xc2, 0x3b, 0x25, 0x0e, 0x1f,
|
||||
0x7a, 0xd3, 0x63, 0x01, 0xa2, 0xdb, 0x00, 0xc2, 0xcd, 0xc2, 0xd4, 0x4a, 0x5e, 0xac, 0x38, 0xcf,
|
||||
0x11, 0x61, 0x26, 0xfa, 0x08, 0x0a, 0x22, 0x3c, 0xc8, 0xd8, 0x76, 0x59, 0x50, 0x81, 0x9d, 0x74,
|
||||
0xbd, 0xb0, 0xa7, 0xef, 0x3a, 0x2e, 0x8f, 0x14, 0xcc, 0x25, 0x87, 0xb6, 0xcb, 0x30, 0xf8, 0xe1,
|
||||
0xcf, 0x00, 0x0d, 0x61, 0x83, 0x87, 0x05, 0x19, 0xcc, 0x02, 0xe6, 0x4d, 0x88, 0x4f, 0x07, 0x9e,
|
||||
0x3f, 0x0c, 0x2a, 0x05, 0x31, 0xf4, 0xc7, 0xbb, 0x51, 0xb4, 0xed, 0x5e, 0x0e, 0xaf, 0xdd, 0x16,
|
||||
0x0d, 0x58, 0x53, 0x8c, 0xc3, 0x72, 0x98, 0xe1, 0x32, 0xff, 0x02, 0xaf, 0x0f, 0x17, 0x71, 0xf4,
|
||||
0x01, 0x20, 0xcb, 0x71, 0xbc, 0x97, 0x24, 0xa0, 0xce, 0x88, 0xa8, 0xbd, 0xac, 0xac, 0xed, 0x68,
|
||||
0xf5, 0x1c, 0xd6, 0x85, 0xa4, 0x47, 0x9d, 0x91, 0x52, 0x8f, 0x3e, 0x81, 0x92, 0xb0, 0x69, 0x44,
|
||||
0x2d, 0x36, 0xf3, 0x69, 0x50, 0xd1, 0x77, 0xd2, 0xf5, 0xf2, 0xde, 0xba, 0x5a, 0xc8, 0x81, 0x84,
|
||||
0xf7, 0x6d, 0x86, 0x8b, 0x9c, 0xa7, 0xbe, 0x03, 0xb4, 0x0d, 0xf9, 0x89, 0xf5, 0x8a, 0x4c, 0x2d,
|
||||
0x9f, 0x05, 0x95, 0xf5, 0x1d, 0xad, 0x5e, 0xc2, 0xb9, 0x89, 0xf5, 0xea, 0x98, 0x7f, 0xa3, 0x5d,
|
||||
0xd8, 0x70, 0x3d, 0x62, 0xbb, 0x23, 0xc7, 0x3e, 0x1b, 0x33, 0x32, 0x9b, 0x0e, 0x2d, 0x46, 0x83,
|
||||
0x0a, 0x12, 0x36, 0xac, 0xbb, 0x9e, 0xa9, 0x24, 0x27, 0x52, 0x80, 0x3e, 0x84, 0x0d, 0xae, 0x2c,
|
||||
0x18, 0x5b, 0xfe, 0x90, 0x04, 0xf6, 0x0f, 0x54, 0x46, 0xc6, 0x0d, 0xbe, 0xe3, 0x58, 0x9f, 0x58,
|
||||
0xaf, 0x7a, 0x5c, 0xd2, 0xb3, 0x7f, 0xa0, 0x3c, 0x3a, 0xaa, 0x2d, 0xb8, 0xb9, 0xdc, 0x1d, 0x3c,
|
||||
0xe1, 0xf8, 0x7e, 0x6a, 0x62, 0x20, 0xff, 0x89, 0x36, 0x61, 0xe5, 0x85, 0xe5, 0xcc, 0xa8, 0x48,
|
||||
0xc2, 0x22, 0x96, 0x1f, 0x3f, 0x4b, 0x7d, 0xa6, 0xd5, 0xc6, 0xb0, 0xd1, 0xf7, 0xad, 0xc1, 0xf9,
|
||||
0x42, 0x1e, 0x2f, 0xa6, 0xa1, 0x76, 0x39, 0x0d, 0xaf, 0x58, 0x5e, 0xea, 0x8a, 0xe5, 0xd5, 0xbe,
|
||||
0x82, 0x35, 0x11, 0x10, 0x07, 0x94, 0x5e, 0x57, 0x2d, 0xb6, 0x80, 0xd7, 0x02, 0x91, 0x38, 0xb2,
|
||||
0x62, 0x64, 0xad, 0x09, 0xcf, 0x99, 0xda, 0x10, 0xf4, 0xf9, 0xf8, 0x60, 0xea, 0xb9, 0x01, 0xe5,
|
||||
0xa5, 0x80, 0xc7, 0x0b, 0x0f, 0x78, 0x9e, 0x4f, 0xc2, 0x5f, 0x9a, 0x18, 0x55, 0x56, 0xf8, 0x01,
|
||||
0x15, 0xde, 0xe2, 0xf1, 0xce, 0xf3, 0x94, 0x38, 0xde, 0xe0, 0x9c, 0xd7, 0x0c, 0xeb, 0x42, 0xa9,
|
||||
0x2f, 0x71, 0xb8, 0xed, 0x0d, 0xce, 0x5b, 0x1c, 0xac, 0x3d, 0x97, 0x65, 0xad, 0xef, 0x89, 0xb9,
|
||||
0xfe, 0x0d, 0x77, 0xd4, 0x60, 0x45, 0x84, 0xae, 0x50, 0x5b, 0xd8, 0x2b, 0xc6, 0x73, 0x00, 0x4b,
|
||||
0x51, 0xed, 0x39, 0x6c, 0x24, 0x94, 0xab, 0x55, 0x54, 0x21, 0x37, 0xf5, 0xa9, 0x3d, 0xb1, 0xce,
|
||||
0xa8, 0xd2, 0x1c, 0x7d, 0xa3, 0x3a, 0xac, 0x8e, 0x2c, 0xdb, 0x99, 0xf9, 0xa1, 0xe2, 0x72, 0x18,
|
||||
0x93, 0x12, 0xc5, 0xa1, 0xb8, 0x76, 0x0b, 0xaa, 0x98, 0x06, 0x94, 0x1d, 0xd9, 0x41, 0x60, 0x7b,
|
||||
0x6e, 0xd3, 0x73, 0x99, 0xef, 0x39, 0x6a, 0x05, 0xb5, 0xdb, 0xb0, 0xbd, 0x54, 0x2a, 0x4d, 0xe0,
|
||||
0x83, 0xbf, 0x99, 0x51, 0xff, 0x62, 0xf9, 0xe0, 0x6f, 0x60, 0x7b, 0xa9, 0x54, 0xd9, 0xff, 0x01,
|
||||
0xac, 0x4c, 0x2d, 0xdb, 0xe7, 0x7b, 0xcf, 0x73, 0xf8, 0x66, 0x2c, 0x87, 0x8f, 0x2d, 0xdb, 0x3f,
|
||||
0xb4, 0x03, 0xe6, 0xf9, 0x17, 0x58, 0x92, 0x1e, 0x67, 0x72, 0x9a, 0x9e, 0xaa, 0xfd, 0x41, 0x83,
|
||||
0x42, 0x4c, 0xc8, 0x33, 0xc9, 0xf5, 0x86, 0x94, 0x8c, 0x7c, 0x6f, 0x12, 0x3a, 0x81, 0x03, 0x07,
|
||||
0xbe, 0x37, 0xe1, 0x31, 0x21, 0x84, 0xcc, 0x53, 0x01, 0x9c, 0xe5, 0x9f, 0x7d, 0x0f, 0x7d, 0x08,
|
||||
0xab, 0x63, 0xa9, 0x40, 0x54, 0xd9, 0xc2, 0xde, 0xc6, 0xc2, 0xdc, 0x2d, 0x8b, 0x59, 0x38, 0xe4,
|
||||
0x3c, 0xce, 0xe4, 0xd2, 0x7a, 0xe6, 0x71, 0x26, 0x97, 0xd1, 0x57, 0x1e, 0x67, 0x72, 0x2b, 0x7a,
|
||||
0xf6, 0x71, 0x26, 0x97, 0xd5, 0x57, 0x6b, 0xff, 0xd0, 0x20, 0x17, 0xb2, 0xb9, 0x25, 0xdc, 0xa5,
|
||||
0x84, 0xc7, 0x85, 0x0a, 0xa6, 0x1c, 0x07, 0xfa, 0xf6, 0x84, 0xa2, 0x1d, 0x28, 0x0a, 0x61, 0x32,
|
||||
0x44, 0x81, 0x63, 0x0d, 0x11, 0xa6, 0xa2, 0xfc, 0x87, 0x0c, 0x11, 0x8f, 0x19, 0x55, 0xfe, 0x25,
|
||||
0x25, 0x3c, 0xe4, 0x82, 0xd9, 0x60, 0x40, 0x83, 0x40, 0xce, 0xb2, 0x22, 0x29, 0x0a, 0x13, 0x13,
|
||||
0xbd, 0x0f, 0x6b, 0x21, 0x25, 0x9c, 0x2b, 0x2b, 0xe3, 0x55, 0xc1, 0x6a, 0xba, 0x3a, 0xe8, 0x71,
|
||||
0xde, 0x64, 0x7e, 0xe0, 0x94, 0xe7, 0x44, 0x3e, 0xa9, 0x5c, 0x7c, 0x6d, 0x07, 0xee, 0x3c, 0x5a,
|
||||
0x8c, 0x82, 0xa6, 0xe7, 0x8e, 0xec, 0xb3, 0x70, 0xb3, 0xbf, 0x87, 0xbb, 0x57, 0x32, 0xd4, 0x86,
|
||||
0x7f, 0x0a, 0xd9, 0x81, 0x40, 0x84, 0x7f, 0x0a, 0x7b, 0x77, 0x63, 0x5e, 0x5f, 0x3a, 0x50, 0xd1,
|
||||
0x6b, 0xcf, 0xe0, 0x4e, 0xef, 0xda, 0xd9, 0xff, 0x73, 0xd5, 0x6f, 0xc3, 0xdd, 0xde, 0xf5, 0x66,
|
||||
0xd7, 0x7e, 0x9d, 0x82, 0xcd, 0x65, 0x04, 0x7e, 0x70, 0x8e, 0x2d, 0x67, 0x44, 0x1c, 0x7b, 0x44,
|
||||
0xa3, 0xd3, 0x5d, 0x96, 0xcf, 0x35, 0x2e, 0x68, 0xdb, 0x23, 0x1a, 0x1e, 0xef, 0xf7, 0x60, 0x4d,
|
||||
0x9c, 0x99, 0xbe, 0x77, 0x6a, 0x9d, 0xda, 0x8e, 0xcd, 0x64, 0x21, 0x49, 0xe1, 0xf2, 0xd8, 0x9b,
|
||||
0x1e, 0xcf, 0x51, 0x74, 0x13, 0xb2, 0x2f, 0x29, 0x2f, 0x80, 0xa2, 0x87, 0x49, 0x61, 0xf5, 0x85,
|
||||
0x3e, 0x81, 0xad, 0x89, 0xf5, 0xca, 0x9e, 0xcc, 0x26, 0x64, 0xde, 0x79, 0x04, 0x33, 0x87, 0x05,
|
||||
0x22, 0x54, 0x4a, 0xf8, 0x86, 0x12, 0x47, 0x25, 0x59, 0x08, 0x51, 0x13, 0xee, 0x4c, 0x6c, 0x57,
|
||||
0x8c, 0x53, 0x29, 0x4f, 0x7c, 0xea, 0x58, 0xaf, 0x88, 0xed, 0x32, 0xea, 0xbf, 0xb0, 0x1c, 0x11,
|
||||
0x46, 0x19, 0xbc, 0xad, 0x58, 0x61, 0x81, 0xe0, 0x1c, 0x53, 0x51, 0x6a, 0xbf, 0x84, 0x2d, 0x91,
|
||||
0xc9, 0x31, 0x43, 0x43, 0xcf, 0xf3, 0xb8, 0xf7, 0xbd, 0x09, 0xe1, 0xa9, 0x15, 0x66, 0x20, 0x07,
|
||||
0x3a, 0xde, 0x90, 0xf2, 0x0c, 0x64, 0x9e, 0x14, 0xa9, 0x0c, 0x64, 0x9e, 0x10, 0xc4, 0x5b, 0xb9,
|
||||
0x74, 0xa2, 0x95, 0xab, 0x9d, 0x43, 0xe5, 0xf2, 0x5c, 0x2a, 0x82, 0x76, 0xa0, 0x10, 0xf7, 0x20,
|
||||
0x9f, 0x4e, 0xc3, 0x71, 0x28, 0x9e, 0xda, 0xa9, 0xd7, 0xa7, 0x76, 0xed, 0x6f, 0x1a, 0xac, 0xef,
|
||||
0xcf, 0x6c, 0x67, 0x98, 0xa8, 0xdb, 0x71, 0xeb, 0xb4, 0x64, 0xa3, 0xb9, 0xac, 0x8b, 0x4c, 0x2d,
|
||||
0xed, 0x22, 0x3f, 0x58, 0xd2, 0x86, 0xa5, 0x45, 0x1b, 0x96, 0x5a, 0xd2, 0x84, 0xdd, 0x85, 0xc2,
|
||||
0xbc, 0xa7, 0xe2, 0x5b, 0x9a, 0xae, 0x17, 0x31, 0x8c, 0xc3, 0x86, 0x2a, 0xb8, 0xd4, 0x94, 0xae,
|
||||
0x5c, 0x6a, 0x4a, 0x6b, 0x9f, 0x01, 0x8a, 0xaf, 0x45, 0xf9, 0x2c, 0x3a, 0x61, 0xb4, 0xab, 0x4f,
|
||||
0x98, 0x5b, 0x50, 0xed, 0xcd, 0x4e, 0x83, 0x81, 0x6f, 0x9f, 0xd2, 0x43, 0xe6, 0x0c, 0x8c, 0x17,
|
||||
0xd4, 0x65, 0x41, 0x98, 0xda, 0xff, 0xcc, 0x40, 0x3e, 0x42, 0xf9, 0x01, 0x6e, 0xbb, 0x03, 0x6f,
|
||||
0x12, 0xae, 0xcb, 0xa5, 0x0e, 0x5f, 0x9a, 0x8c, 0xfb, 0xf5, 0x50, 0xd4, 0x94, 0x12, 0x73, 0xc8,
|
||||
0xf9, 0x09, 0x3f, 0x28, 0x7e, 0x4a, 0xf2, 0xe3, 0x6e, 0x90, 0xfc, 0x3a, 0xe8, 0x91, 0xfe, 0x31,
|
||||
0x73, 0x06, 0x91, 0xdf, 0x70, 0x39, 0xc4, 0xb9, 0x31, 0x92, 0x19, 0x69, 0x0e, 0x99, 0x19, 0xc9,
|
||||
0x0c, 0x71, 0xc5, 0x7c, 0x1b, 0x8a, 0xbc, 0x62, 0x06, 0xcc, 0x9a, 0x4c, 0x89, 0x1b, 0xa8, 0x90,
|
||||
0x2f, 0x44, 0x58, 0x27, 0x40, 0x5f, 0x02, 0x50, 0xbe, 0x3e, 0xc2, 0x2e, 0xa6, 0x54, 0x14, 0xcd,
|
||||
0xf2, 0xde, 0x9d, 0x58, 0xec, 0x44, 0x0e, 0xd8, 0x15, 0xff, 0xf6, 0x2f, 0xa6, 0x14, 0xe7, 0x69,
|
||||
0xf8, 0x13, 0x7d, 0x05, 0xa5, 0x91, 0xe7, 0xbf, 0xe4, 0x3d, 0x98, 0x00, 0xd5, 0xc1, 0xb2, 0x15,
|
||||
0xd3, 0x70, 0x20, 0xe5, 0x62, 0xf8, 0xe1, 0x5b, 0xb8, 0x38, 0x8a, 0x7d, 0xa3, 0x27, 0x80, 0xc2,
|
||||
0xf1, 0xe2, 0x1c, 0x90, 0x4a, 0x72, 0x42, 0xc9, 0xf6, 0x65, 0x25, 0x3c, 0x4b, 0x43, 0x45, 0xfa,
|
||||
0x68, 0x01, 0x43, 0x9f, 0x43, 0x31, 0xa0, 0x8c, 0x39, 0x54, 0xa9, 0xc9, 0x0b, 0x35, 0x37, 0x13,
|
||||
0x4d, 0x32, 0x17, 0x87, 0x1a, 0x0a, 0xc1, 0xfc, 0x13, 0xed, 0xc3, 0x9a, 0x63, 0xbb, 0xe7, 0x71,
|
||||
0x33, 0x40, 0x8c, 0xaf, 0xc4, 0xc6, 0xb7, 0x6d, 0xf7, 0x3c, 0x6e, 0x43, 0xc9, 0x89, 0x03, 0xb5,
|
||||
0x2f, 0x20, 0x1f, 0x79, 0x09, 0x15, 0x60, 0xf5, 0xa4, 0xf3, 0xa4, 0xd3, 0xfd, 0xb6, 0xa3, 0xbf,
|
||||
0x85, 0x72, 0x90, 0xe9, 0x19, 0x9d, 0x96, 0xae, 0x71, 0x18, 0x1b, 0x4d, 0xc3, 0x7c, 0x6a, 0xe8,
|
||||
0x29, 0xfe, 0x71, 0xd0, 0xc5, 0xdf, 0x36, 0x70, 0x4b, 0x4f, 0xef, 0xaf, 0xc2, 0x8a, 0x98, 0xb7,
|
||||
0xf6, 0x27, 0x0d, 0x72, 0x62, 0x07, 0xdd, 0x91, 0x87, 0x7e, 0x04, 0x51, 0x70, 0x89, 0xe3, 0x8f,
|
||||
0xb7, 0x64, 0x22, 0xea, 0x4a, 0x38, 0x0a, 0x98, 0xbe, 0xc2, 0x39, 0x39, 0x0a, 0x8d, 0x88, 0x9c,
|
||||
0x92, 0xe4, 0x50, 0x10, 0x91, 0xef, 0xc7, 0x34, 0x27, 0xaa, 0x52, 0x06, 0xaf, 0x85, 0x82, 0xf0,
|
||||
0x0c, 0x8e, 0x5f, 0x96, 0x12, 0x67, 0x75, 0xec, 0xb2, 0xa4, 0xb8, 0xb5, 0x4f, 0xa1, 0x18, 0xdf,
|
||||
0x73, 0x74, 0x0f, 0x32, 0xb6, 0x3b, 0xf2, 0x54, 0x22, 0x6e, 0x2c, 0x04, 0x17, 0x5f, 0x24, 0x16,
|
||||
0x84, 0x1a, 0x02, 0x7d, 0x71, 0x9f, 0x6b, 0x25, 0x28, 0xc4, 0x36, 0xad, 0xf6, 0x77, 0x0d, 0x4a,
|
||||
0x89, 0x4d, 0x78, 0x63, 0xed, 0xe8, 0x4b, 0x28, 0xbe, 0xb4, 0x7d, 0x4a, 0xe2, 0x0d, 0x62, 0x79,
|
||||
0xaf, 0x9a, 0x6c, 0x10, 0xc3, 0xff, 0x9b, 0xde, 0x90, 0xe2, 0x02, 0xe7, 0x2b, 0x00, 0xfd, 0x1c,
|
||||
0xca, 0xe1, 0x41, 0x32, 0xa4, 0xcc, 0xb2, 0x1d, 0xe1, 0xaa, 0x72, 0x22, 0x3c, 0x14, 0xb7, 0x25,
|
||||
0xe4, 0xb8, 0x34, 0x8a, 0x7f, 0xa2, 0xf7, 0xe6, 0x0a, 0x02, 0xe6, 0xdb, 0xee, 0x99, 0xf0, 0x5f,
|
||||
0x3e, 0xa2, 0xf5, 0x04, 0xc8, 0x5b, 0xbd, 0x92, 0x3a, 0xcb, 0x7a, 0xcc, 0x62, 0x33, 0x7e, 0xd3,
|
||||
0x59, 0x09, 0x98, 0xa5, 0x2a, 0x59, 0x39, 0x91, 0x5b, 0x31, 0x22, 0xc5, 0x92, 0x95, 0xe8, 0x8f,
|
||||
0x53, 0x97, 0xfa, 0xe3, 0x15, 0x5e, 0x31, 0x64, 0xa1, 0x2d, 0xec, 0x21, 0xb5, 0xf8, 0xc3, 0x7e,
|
||||
0xbb, 0xd9, 0x60, 0x8c, 0x4e, 0xa6, 0x0c, 0x4b, 0x82, 0xea, 0x7f, 0xbe, 0x02, 0x68, 0xda, 0xfe,
|
||||
0x60, 0x66, 0xb3, 0x27, 0xf4, 0x82, 0x1f, 0x6b, 0x61, 0x45, 0x97, 0x65, 0x2f, 0x3b, 0x90, 0x55,
|
||||
0x7c, 0x0b, 0x56, 0xc3, 0x42, 0x24, 0xeb, 0x5b, 0x76, 0x2c, 0x0a, 0x50, 0xed, 0xcf, 0x19, 0xd8,
|
||||
0x56, 0x5b, 0x2a, 0x77, 0x83, 0x51, 0x7f, 0x40, 0xa7, 0xd1, 0xc5, 0xe9, 0x11, 0x6c, 0xce, 0x8b,
|
||||
0xaa, 0x9c, 0x88, 0x84, 0x97, 0xb1, 0xc2, 0xde, 0x8d, 0xd8, 0x4a, 0xe7, 0x66, 0x60, 0x14, 0x15,
|
||||
0xdb, 0xb9, 0x69, 0x0f, 0x63, 0x8a, 0xac, 0x89, 0x37, 0x73, 0x55, 0x88, 0xca, 0x8a, 0x87, 0xe6,
|
||||
0xe1, 0xcc, 0x45, 0x22, 0xa2, 0xef, 0x41, 0x14, 0xe4, 0x84, 0xbe, 0x9a, 0xda, 0xfe, 0x85, 0xa8,
|
||||
0x7e, 0xa5, 0x79, 0xb9, 0x35, 0x04, 0x7a, 0xe9, 0x36, 0x93, 0xba, 0x7c, 0x9b, 0xf9, 0x1c, 0xaa,
|
||||
0x51, 0x76, 0xa8, 0x77, 0x11, 0x3a, 0x8c, 0x4e, 0xbf, 0x55, 0x61, 0xc3, 0x56, 0xc8, 0xc0, 0x21,
|
||||
0x41, 0x1d, 0x81, 0x0f, 0x61, 0x33, 0x96, 0x5a, 0x73, 0xd3, 0x65, 0x26, 0xa2, 0x79, 0x76, 0xc5,
|
||||
0x4d, 0x8f, 0x46, 0x28, 0xd3, 0x65, 0x2f, 0x14, 0xd5, 0x7f, 0x65, 0xfa, 0x2f, 0xa0, 0xbc, 0xf0,
|
||||
0x6e, 0x90, 0x13, 0xfb, 0xfe, 0xd3, 0xcb, 0x95, 0x75, 0xd9, 0xf6, 0xec, 0x2e, 0x79, 0x3c, 0x28,
|
||||
0x0d, 0x12, 0x0f, 0x07, 0xb7, 0x01, 0x3c, 0xd7, 0xf6, 0x5c, 0x72, 0xea, 0x78, 0xa7, 0xa2, 0xe0,
|
||||
0x16, 0x71, 0x5e, 0x20, 0xfb, 0x8e, 0x77, 0x5a, 0xfd, 0x1a, 0xd0, 0x7f, 0x79, 0xe3, 0xfe, 0x8b,
|
||||
0x06, 0xb7, 0x96, 0x9b, 0xa8, 0xce, 0xf9, 0xff, 0x59, 0x08, 0x7d, 0x0e, 0x59, 0x6b, 0xc0, 0x6c,
|
||||
0xcf, 0x55, 0x95, 0xe1, 0x9d, 0xd8, 0x50, 0x4c, 0x03, 0xcf, 0x79, 0x41, 0x0f, 0x3d, 0x67, 0xa8,
|
||||
0x8c, 0x69, 0x08, 0x2a, 0x56, 0x43, 0x12, 0x49, 0x97, 0x4e, 0x26, 0x5d, 0xed, 0xb7, 0x1a, 0x6c,
|
||||
0xc9, 0x6b, 0x3d, 0xdf, 0x71, 0x99, 0xd4, 0x61, 0x02, 0xec, 0x01, 0x88, 0x30, 0x99, 0x7a, 0xb6,
|
||||
0xcb, 0xa2, 0x1a, 0x26, 0xb3, 0x52, 0xf5, 0x06, 0xc7, 0x5c, 0x84, 0xf3, 0x9c, 0x26, 0x7e, 0xa2,
|
||||
0x8f, 0x17, 0x0c, 0x8d, 0x9f, 0x93, 0xf3, 0x19, 0x92, 0x06, 0xd6, 0xaa, 0x50, 0xb9, 0x6c, 0x83,
|
||||
0x74, 0xe1, 0xfd, 0xdf, 0x64, 0xa0, 0x94, 0x28, 0x5d, 0xc9, 0xb3, 0xab, 0x04, 0xf9, 0x4e, 0x97,
|
||||
0xb4, 0x8c, 0x7e, 0xc3, 0x6c, 0xeb, 0x1a, 0xd2, 0xa1, 0xd8, 0xed, 0x98, 0xdd, 0x0e, 0x69, 0x19,
|
||||
0xcd, 0x6e, 0x8b, 0x9f, 0x62, 0x37, 0x60, 0xbd, 0x6d, 0x76, 0x9e, 0x90, 0x4e, 0xb7, 0x4f, 0x8c,
|
||||
0xb6, 0xf9, 0xc8, 0xdc, 0x6f, 0x1b, 0x7a, 0x1a, 0x6d, 0x82, 0xde, 0xed, 0x90, 0xe6, 0x61, 0xc3,
|
||||
0xec, 0x90, 0xbe, 0x79, 0x64, 0x74, 0x4f, 0xfa, 0x7a, 0x86, 0xa3, 0xbc, 0xdc, 0x10, 0xe3, 0xbb,
|
||||
0xa6, 0x61, 0xb4, 0x7a, 0xe4, 0xa8, 0xf1, 0x9d, 0xbe, 0x82, 0x2a, 0xb0, 0x69, 0x76, 0x7a, 0x27,
|
||||
0x07, 0x07, 0x66, 0xd3, 0x34, 0x3a, 0x7d, 0xb2, 0xdf, 0x68, 0x37, 0x3a, 0x4d, 0x43, 0xcf, 0xa2,
|
||||
0x9b, 0x80, 0xcc, 0x4e, 0xb3, 0x7b, 0x74, 0xdc, 0x36, 0xfa, 0x06, 0x09, 0x4f, 0xcb, 0x55, 0xb4,
|
||||
0x01, 0x6b, 0x42, 0x4f, 0xa3, 0xd5, 0x22, 0x07, 0x0d, 0xb3, 0x6d, 0xb4, 0xf4, 0x1c, 0xb7, 0x44,
|
||||
0x31, 0x7a, 0xa4, 0x65, 0xf6, 0x1a, 0xfb, 0x1c, 0xce, 0xf3, 0x39, 0xcd, 0xce, 0xd3, 0xae, 0xd9,
|
||||
0x34, 0x48, 0x93, 0xab, 0xe5, 0x28, 0x70, 0x72, 0x88, 0x9e, 0x74, 0x5a, 0x06, 0x3e, 0x6e, 0x98,
|
||||
0x2d, 0xbd, 0x80, 0xb6, 0x61, 0x2b, 0x84, 0x8d, 0xef, 0x8e, 0x4d, 0xfc, 0x8c, 0xf4, 0xbb, 0x5d,
|
||||
0xd2, 0xeb, 0x76, 0x3b, 0x7a, 0x31, 0xae, 0x89, 0xaf, 0xb6, 0x7b, 0x6c, 0x74, 0xf4, 0x12, 0xda,
|
||||
0x82, 0x8d, 0xa3, 0xe3, 0x63, 0x12, 0x4a, 0xc2, 0xc5, 0x96, 0x39, 0xbd, 0xd1, 0x6a, 0x61, 0xa3,
|
||||
0xd7, 0x23, 0x47, 0x66, 0xef, 0xa8, 0xd1, 0x6f, 0x1e, 0xea, 0x6b, 0x7c, 0x49, 0x3d, 0xa3, 0x4f,
|
||||
0xfa, 0xdd, 0x7e, 0xa3, 0x3d, 0xc7, 0x75, 0x6e, 0xd0, 0x1c, 0xe7, 0x93, 0xb6, 0xbb, 0xdf, 0xea,
|
||||
0xeb, 0xdc, 0xe1, 0x1c, 0xee, 0x3e, 0x55, 0x26, 0x22, 0xbe, 0x76, 0xb5, 0x3d, 0xe1, 0x9c, 0xfa,
|
||||
0x06, 0x07, 0xcd, 0xce, 0xd3, 0x46, 0xdb, 0x6c, 0x91, 0x27, 0xc6, 0x33, 0xd1, 0x6d, 0x6c, 0x72,
|
||||
0x50, 0x5a, 0x46, 0x8e, 0x71, 0xf7, 0x11, 0x37, 0x44, 0xbf, 0x81, 0x10, 0x94, 0x9b, 0x26, 0x6e,
|
||||
0x9e, 0xb4, 0x1b, 0x98, 0xe0, 0xee, 0x49, 0xdf, 0xd0, 0x6f, 0xde, 0xff, 0xa3, 0x06, 0xc5, 0xf8,
|
||||
0x69, 0xc2, 0x77, 0xdd, 0xec, 0x90, 0x83, 0xb6, 0xf9, 0xe8, 0xb0, 0x2f, 0x83, 0xa0, 0x77, 0xd2,
|
||||
0xe4, 0x5b, 0x66, 0xf0, 0x2e, 0x06, 0x41, 0x59, 0x3a, 0x3d, 0x5a, 0x6c, 0x8a, 0xcf, 0xa5, 0xb0,
|
||||
0x4e, 0x57, 0xe9, 0x4d, 0x73, 0xe3, 0x15, 0x68, 0x60, 0xdc, 0xc5, 0x7a, 0x06, 0xbd, 0x0b, 0x3b,
|
||||
0x0a, 0xe1, 0xfb, 0x8a, 0xb1, 0xd1, 0xec, 0x93, 0xe3, 0xc6, 0xb3, 0x23, 0xbe, 0xed, 0x32, 0xc8,
|
||||
0x7a, 0xfa, 0x0a, 0xba, 0x0b, 0xdb, 0x11, 0x6b, 0x59, 0x5c, 0xdc, 0xff, 0x02, 0x2a, 0x57, 0x65,
|
||||
0x25, 0x02, 0xc8, 0xf6, 0x8c, 0x7e, 0xbf, 0x6d, 0xc8, 0xce, 0xeb, 0x40, 0x06, 0x2e, 0x40, 0x16,
|
||||
0x1b, 0xbd, 0x93, 0x23, 0x43, 0x4f, 0xdd, 0xff, 0x09, 0xe8, 0x8b, 0xa9, 0xc2, 0xe5, 0x46, 0x87,
|
||||
0x87, 0x8c, 0xfe, 0x16, 0x4f, 0x00, 0x15, 0x3f, 0xba, 0xc6, 0x55, 0x34, 0x4e, 0xfa, 0x5d, 0x3d,
|
||||
0xb5, 0xf7, 0xbb, 0x02, 0x64, 0xc5, 0x0d, 0xc2, 0x47, 0x5f, 0x43, 0x29, 0xf6, 0xe4, 0xfa, 0x74,
|
||||
0x0f, 0xdd, 0xbe, 0xf6, 0x31, 0xb6, 0x1a, 0xbe, 0x44, 0x29, 0xf8, 0xa1, 0x86, 0xf6, 0xa1, 0x1c,
|
||||
0x7f, 0x4c, 0x7c, 0xba, 0x87, 0xe2, 0x8d, 0xf7, 0x92, 0x77, 0xc6, 0x25, 0x3a, 0x9e, 0x80, 0x6e,
|
||||
0x04, 0xcc, 0x9e, 0xf0, 0xf3, 0x5f, 0x3d, 0xf7, 0xa1, 0x6a, 0xbc, 0x70, 0x25, 0xdf, 0x10, 0xab,
|
||||
0xdb, 0x4b, 0x65, 0xaa, 0x94, 0x7e, 0xc3, 0x7b, 0xad, 0xe8, 0xc1, 0xed, 0xd2, 0x82, 0x92, 0xaf,
|
||||
0x7c, 0xd5, 0x3b, 0x57, 0x89, 0xd5, 0xfb, 0x41, 0xfa, 0xf7, 0x29, 0xbe, 0xc6, 0x52, 0x4c, 0xb6,
|
||||
0xc4, 0x4b, 0x0b, 0x4a, 0x97, 0x74, 0x24, 0x68, 0x08, 0x1b, 0x4b, 0x1e, 0xe3, 0xd0, 0x7b, 0xc9,
|
||||
0xfa, 0x7c, 0xc5, 0x53, 0x5e, 0xf5, 0xfd, 0xd7, 0xd1, 0xd4, 0xe2, 0x87, 0xb0, 0xb1, 0xe4, 0xd5,
|
||||
0x2e, 0x31, 0xcb, 0xd5, 0x6f, 0x7e, 0x89, 0x59, 0xae, 0x7b, 0xfc, 0x9b, 0xc2, 0xd6, 0x15, 0xcf,
|
||||
0x45, 0xe8, 0xff, 0x63, 0x2a, 0xae, 0x7f, 0x74, 0xaa, 0xde, 0x7f, 0x13, 0xea, 0x7c, 0xc6, 0xde,
|
||||
0x1b, 0xcc, 0xd8, 0x7b, 0xf3, 0x19, 0x5f, 0xf3, 0x70, 0x84, 0x9e, 0x83, 0xbe, 0xf8, 0x92, 0x81,
|
||||
0x6a, 0x8b, 0xfe, 0xb9, 0xfc, 0xa4, 0x52, 0x7d, 0xe7, 0x5a, 0x8e, 0x52, 0x6e, 0x02, 0xcc, 0x2f,
|
||||
0xfb, 0xe8, 0x56, 0x6c, 0xc8, 0xa5, 0xf7, 0x8c, 0xea, 0xed, 0x2b, 0xa4, 0x4a, 0x55, 0x1f, 0x36,
|
||||
0x96, 0xdc, 0xfe, 0x13, 0x3b, 0x7e, 0xf5, 0xeb, 0x40, 0x75, 0x73, 0xd9, 0x25, 0xf9, 0xa1, 0x86,
|
||||
0x8e, 0x64, 0x12, 0x85, 0x7f, 0x2b, 0x79, 0x4d, 0x55, 0xa8, 0x2c, 0x6f, 0xe6, 0x67, 0x81, 0x48,
|
||||
0x9f, 0x87, 0x1a, 0xea, 0x42, 0x31, 0x5e, 0x09, 0x5e, 0x5b, 0x22, 0x5e, 0xab, 0x70, 0x04, 0x6b,
|
||||
0x89, 0x46, 0xca, 0xf3, 0xd1, 0xbd, 0xd7, 0xb6, 0x83, 0xd2, 0x63, 0x89, 0x28, 0xbf, 0xa6, 0x6f,
|
||||
0xac, 0xf3, 0x79, 0x9e, 0x83, 0xbe, 0xd8, 0x70, 0x24, 0xa2, 0xe0, 0x8a, 0x8e, 0x28, 0x11, 0x05,
|
||||
0x57, 0x75, 0x2c, 0xfb, 0x1f, 0x7d, 0xff, 0xe0, 0xcc, 0x66, 0xe3, 0xd9, 0xe9, 0xee, 0xc0, 0x9b,
|
||||
0x3c, 0x10, 0x7f, 0x38, 0x71, 0x6d, 0xf7, 0xcc, 0xa5, 0xec, 0xa5, 0xe7, 0x9f, 0x3f, 0x70, 0xdc,
|
||||
0xe1, 0x03, 0x51, 0x47, 0x1e, 0x44, 0xba, 0x4e, 0xb3, 0xe2, 0x2f, 0xb1, 0x1f, 0xff, 0x2b, 0x00,
|
||||
0x00, 0xff, 0xff, 0xe2, 0xcb, 0x48, 0x96, 0xb9, 0x1d, 0x00, 0x00,
|
||||
}
|
||||
|
||||
// Reference imports to suppress errors if they are not otherwise used.
|
||||
@ -2567,6 +2682,12 @@ type RouterClient interface {
|
||||
//In case of interception, the htlc can be either settled, cancelled or
|
||||
//resumed later by using the ResolveHoldForward endpoint.
|
||||
HtlcInterceptor(ctx context.Context, opts ...grpc.CallOption) (Router_HtlcInterceptorClient, error)
|
||||
//
|
||||
//UpdateChanStatus attempts to manually set the state of a channel
|
||||
//(enabled, disabled, or auto). A manual "disable" request will cause the
|
||||
//channel to stay disabled until a subsequent manual request of either
|
||||
//"enable" or "auto".
|
||||
UpdateChanStatus(ctx context.Context, in *UpdateChanStatusRequest, opts ...grpc.CallOption) (*UpdateChanStatusResponse, error)
|
||||
}
|
||||
|
||||
type routerClient struct {
|
||||
@ -2852,6 +2973,15 @@ func (x *routerHtlcInterceptorClient) Recv() (*ForwardHtlcInterceptRequest, erro
|
||||
return m, nil
|
||||
}
|
||||
|
||||
func (c *routerClient) UpdateChanStatus(ctx context.Context, in *UpdateChanStatusRequest, opts ...grpc.CallOption) (*UpdateChanStatusResponse, error) {
|
||||
out := new(UpdateChanStatusResponse)
|
||||
err := c.cc.Invoke(ctx, "/routerrpc.Router/UpdateChanStatus", in, out, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// RouterServer is the server API for Router service.
|
||||
type RouterServer interface {
|
||||
//
|
||||
@ -2924,6 +3054,12 @@ type RouterServer interface {
|
||||
//In case of interception, the htlc can be either settled, cancelled or
|
||||
//resumed later by using the ResolveHoldForward endpoint.
|
||||
HtlcInterceptor(Router_HtlcInterceptorServer) error
|
||||
//
|
||||
//UpdateChanStatus attempts to manually set the state of a channel
|
||||
//(enabled, disabled, or auto). A manual "disable" request will cause the
|
||||
//channel to stay disabled until a subsequent manual request of either
|
||||
//"enable" or "auto".
|
||||
UpdateChanStatus(context.Context, *UpdateChanStatusRequest) (*UpdateChanStatusResponse, error)
|
||||
}
|
||||
|
||||
// UnimplementedRouterServer can be embedded to have forward compatible implementations.
|
||||
@ -2975,6 +3111,9 @@ func (*UnimplementedRouterServer) TrackPayment(req *TrackPaymentRequest, srv Rou
|
||||
func (*UnimplementedRouterServer) HtlcInterceptor(srv Router_HtlcInterceptorServer) error {
|
||||
return status.Errorf(codes.Unimplemented, "method HtlcInterceptor not implemented")
|
||||
}
|
||||
func (*UnimplementedRouterServer) UpdateChanStatus(ctx context.Context, req *UpdateChanStatusRequest) (*UpdateChanStatusResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method UpdateChanStatus not implemented")
|
||||
}
|
||||
|
||||
func RegisterRouterServer(s *grpc.Server, srv RouterServer) {
|
||||
s.RegisterService(&_Router_serviceDesc, srv)
|
||||
@ -3273,6 +3412,24 @@ func (x *routerHtlcInterceptorServer) Recv() (*ForwardHtlcInterceptResponse, err
|
||||
return m, nil
|
||||
}
|
||||
|
||||
func _Router_UpdateChanStatus_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(UpdateChanStatusRequest)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(RouterServer).UpdateChanStatus(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: "/routerrpc.Router/UpdateChanStatus",
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(RouterServer).UpdateChanStatus(ctx, req.(*UpdateChanStatusRequest))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
var _Router_serviceDesc = grpc.ServiceDesc{
|
||||
ServiceName: "routerrpc.Router",
|
||||
HandlerType: (*RouterServer)(nil),
|
||||
@ -3313,6 +3470,10 @@ var _Router_serviceDesc = grpc.ServiceDesc{
|
||||
MethodName: "BuildRoute",
|
||||
Handler: _Router_BuildRoute_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "UpdateChanStatus",
|
||||
Handler: _Router_UpdateChanStatus_Handler,
|
||||
},
|
||||
},
|
||||
Streams: []grpc.StreamDesc{
|
||||
{
|
||||
|
@ -121,6 +121,15 @@ service Router {
|
||||
*/
|
||||
rpc HtlcInterceptor (stream ForwardHtlcInterceptResponse)
|
||||
returns (stream ForwardHtlcInterceptRequest);
|
||||
|
||||
/*
|
||||
UpdateChanStatus attempts to manually set the state of a channel
|
||||
(enabled, disabled, or auto). A manual "disable" request will cause the
|
||||
channel to stay disabled until a subsequent manual request of either
|
||||
"enable" or "auto".
|
||||
*/
|
||||
rpc UpdateChanStatus (UpdateChanStatusRequest)
|
||||
returns (UpdateChanStatusResponse);
|
||||
}
|
||||
|
||||
message SendPaymentRequest {
|
||||
@ -750,3 +759,18 @@ enum ResolveHoldForwardAction {
|
||||
FAIL = 1;
|
||||
RESUME = 2;
|
||||
}
|
||||
|
||||
message UpdateChanStatusRequest {
|
||||
lnrpc.ChannelPoint chan_point = 1;
|
||||
|
||||
ChanStatusAction action = 2;
|
||||
}
|
||||
|
||||
enum ChanStatusAction {
|
||||
ENABLE = 0;
|
||||
DISABLE = 1;
|
||||
AUTO = 2;
|
||||
}
|
||||
|
||||
message UpdateChanStatusResponse {
|
||||
}
|
||||
|
@ -408,6 +408,25 @@
|
||||
],
|
||||
"default": "IN_FLIGHT"
|
||||
},
|
||||
"lnrpcChannelPoint": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"funding_txid_bytes": {
|
||||
"type": "string",
|
||||
"format": "byte",
|
||||
"description": "Txid of the funding transaction. When using REST, this field must be\nencoded as base64."
|
||||
},
|
||||
"funding_txid_str": {
|
||||
"type": "string",
|
||||
"description": "Hex-encoded string representing the byte-reversed hash of the funding\ntransaction."
|
||||
},
|
||||
"output_index": {
|
||||
"type": "integer",
|
||||
"format": "int64",
|
||||
"title": "The index of the output of the funding transaction"
|
||||
}
|
||||
}
|
||||
},
|
||||
"lnrpcChannelUpdate": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
@ -884,6 +903,15 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"routerrpcChanStatusAction": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"ENABLE",
|
||||
"DISABLE",
|
||||
"AUTO"
|
||||
],
|
||||
"default": "ENABLE"
|
||||
},
|
||||
"routerrpcCircuitKey": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
@ -1448,6 +1476,9 @@
|
||||
"routerrpcSettleEvent": {
|
||||
"type": "object"
|
||||
},
|
||||
"routerrpcUpdateChanStatusResponse": {
|
||||
"type": "object"
|
||||
},
|
||||
"runtimeError": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
|
@ -9,8 +9,8 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/btcsuite/btcd/btcec"
|
||||
|
||||
"github.com/btcsuite/btcd/chaincfg"
|
||||
"github.com/btcsuite/btcd/wire"
|
||||
"github.com/btcsuite/btcutil"
|
||||
"github.com/lightningnetwork/lnd/channeldb"
|
||||
"github.com/lightningnetwork/lnd/htlcswitch"
|
||||
@ -83,6 +83,16 @@ type RouterBackend struct {
|
||||
// InterceptableForwarder exposes the ability to intercept forward events
|
||||
// by letting the router register a ForwardInterceptor.
|
||||
InterceptableForwarder htlcswitch.InterceptableHtlcForwarder
|
||||
|
||||
// SetChannelEnabled exposes the ability to manually enable a channel.
|
||||
SetChannelEnabled func(wire.OutPoint) error
|
||||
|
||||
// SetChannelDisabled exposes the ability to manually disable a channel
|
||||
SetChannelDisabled func(wire.OutPoint) error
|
||||
|
||||
// SetChannelAuto exposes the ability to restore automatic channel state
|
||||
// management after manually setting channel status.
|
||||
SetChannelAuto func(wire.OutPoint) error
|
||||
}
|
||||
|
||||
// MissionControl defines the mission control dependencies of routerrpc.
|
||||
|
@ -10,6 +10,7 @@ import (
|
||||
"sync/atomic"
|
||||
"time"
|
||||
|
||||
"github.com/btcsuite/btcd/wire"
|
||||
"github.com/btcsuite/btcutil"
|
||||
"github.com/grpc-ecosystem/grpc-gateway/runtime"
|
||||
"github.com/lightningnetwork/lnd/channeldb"
|
||||
@ -116,6 +117,10 @@ var (
|
||||
Entity: "offchain",
|
||||
Action: "write",
|
||||
}},
|
||||
"/routerrpc.Router/UpdateChanStatus": {{
|
||||
Entity: "offchain",
|
||||
Action: "write",
|
||||
}},
|
||||
}
|
||||
|
||||
// DefaultRouterMacFilename is the default name of the router macaroon
|
||||
@ -698,3 +703,44 @@ func (s *Server) HtlcInterceptor(stream Router_HtlcInterceptorServer) error {
|
||||
// run the forward interceptor.
|
||||
return newForwardInterceptor(s, stream).run()
|
||||
}
|
||||
|
||||
func extractOutPoint(req *UpdateChanStatusRequest) (*wire.OutPoint, error) {
|
||||
chanPoint := req.GetChanPoint()
|
||||
txid, err := lnrpc.GetChanPointFundingTxid(chanPoint)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
index := chanPoint.OutputIndex
|
||||
return wire.NewOutPoint(txid, index), nil
|
||||
}
|
||||
|
||||
// UpdateChanStatus allows channel state to be set manually.
|
||||
func (s *Server) UpdateChanStatus(ctx context.Context,
|
||||
req *UpdateChanStatusRequest) (*UpdateChanStatusResponse, error) {
|
||||
|
||||
outPoint, err := extractOutPoint(req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
action := req.GetAction()
|
||||
|
||||
log.Debugf("UpdateChanStatus called for channel(%v) with "+
|
||||
"action %v", outPoint, action)
|
||||
|
||||
switch action {
|
||||
case ChanStatusAction_ENABLE:
|
||||
err = s.cfg.RouterBackend.SetChannelEnabled(*outPoint)
|
||||
case ChanStatusAction_DISABLE:
|
||||
err = s.cfg.RouterBackend.SetChannelDisabled(*outPoint)
|
||||
case ChanStatusAction_AUTO:
|
||||
err = s.cfg.RouterBackend.SetChannelAuto(*outPoint)
|
||||
default:
|
||||
err = fmt.Errorf("unrecognized ChannelStatusAction %v", action)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &UpdateChanStatusResponse{}, nil
|
||||
}
|
||||
|
@ -5,6 +5,7 @@ import (
|
||||
"errors"
|
||||
"sort"
|
||||
|
||||
"github.com/btcsuite/btcd/chaincfg/chainhash"
|
||||
"github.com/lightningnetwork/lnd/lnwallet"
|
||||
)
|
||||
|
||||
@ -88,3 +89,26 @@ func ExtractMinConfs(minConfs int32, spendUnconfirmed bool) (int32, error) {
|
||||
return minConfs, nil
|
||||
}
|
||||
}
|
||||
|
||||
// GetChanPointFundingTxid returns the given channel point's funding txid in
|
||||
// raw bytes.
|
||||
func GetChanPointFundingTxid(chanPoint *ChannelPoint) (*chainhash.Hash, error) {
|
||||
var txid []byte
|
||||
|
||||
// A channel point's funding txid can be get/set as a byte slice or a
|
||||
// string. In the case it is a string, decode it.
|
||||
switch chanPoint.GetFundingTxid().(type) {
|
||||
case *ChannelPoint_FundingTxidBytes:
|
||||
txid = chanPoint.GetFundingTxidBytes()
|
||||
case *ChannelPoint_FundingTxidStr:
|
||||
s := chanPoint.GetFundingTxidStr()
|
||||
h, err := chainhash.NewHashFromStr(s)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
txid = h[:]
|
||||
}
|
||||
|
||||
return chainhash.NewHash(txid)
|
||||
}
|
||||
|
@ -9,7 +9,6 @@ import (
|
||||
|
||||
"github.com/btcsuite/btcd/wire"
|
||||
"github.com/btcsuite/btcutil"
|
||||
"github.com/lightningnetwork/lnd"
|
||||
"github.com/lightningnetwork/lnd/chainreg"
|
||||
"github.com/lightningnetwork/lnd/lnrpc"
|
||||
"github.com/lightningnetwork/lnd/lnrpc/routerrpc"
|
||||
@ -341,7 +340,7 @@ func (c *interceptorTestContext) waitForChannels() {
|
||||
// Wait for all nodes to have seen all channels.
|
||||
for _, chanPoint := range c.networkChans {
|
||||
for _, node := range c.nodes {
|
||||
txid, err := lnd.GetChanPointFundingTxid(chanPoint)
|
||||
txid, err := lnrpc.GetChanPointFundingTxid(chanPoint)
|
||||
require.NoError(c.t.t, err, "unable to get txid")
|
||||
|
||||
point := wire.OutPoint{
|
||||
|
@ -8,7 +8,6 @@ import (
|
||||
|
||||
"github.com/btcsuite/btcd/wire"
|
||||
"github.com/btcsuite/btcutil"
|
||||
"github.com/lightningnetwork/lnd"
|
||||
"github.com/lightningnetwork/lnd/chainreg"
|
||||
"github.com/lightningnetwork/lnd/lnrpc"
|
||||
"github.com/lightningnetwork/lnd/lnrpc/routerrpc"
|
||||
@ -376,7 +375,7 @@ func (c *mppTestContext) waitForChannels() {
|
||||
// Wait for all nodes to have seen all channels.
|
||||
for _, chanPoint := range c.networkChans {
|
||||
for _, node := range c.nodes {
|
||||
txid, err := lnd.GetChanPointFundingTxid(chanPoint)
|
||||
txid, err := lnrpc.GetChanPointFundingTxid(chanPoint)
|
||||
if err != nil {
|
||||
c.t.Fatalf("unable to get txid: %v", err)
|
||||
}
|
||||
|
@ -6,7 +6,6 @@ import (
|
||||
|
||||
"github.com/btcsuite/btcd/wire"
|
||||
"github.com/btcsuite/btcutil"
|
||||
"github.com/lightningnetwork/lnd"
|
||||
"github.com/lightningnetwork/lnd/chainreg"
|
||||
"github.com/lightningnetwork/lnd/lnrpc"
|
||||
"github.com/lightningnetwork/lnd/lnrpc/routerrpc"
|
||||
@ -30,7 +29,7 @@ func testMultiHopPayments(net *lntest.NetworkHarness, t *harnessTest) {
|
||||
)
|
||||
networkChans = append(networkChans, chanPointAlice)
|
||||
|
||||
aliceChanTXID, err := lnd.GetChanPointFundingTxid(chanPointAlice)
|
||||
aliceChanTXID, err := lnrpc.GetChanPointFundingTxid(chanPointAlice)
|
||||
if err != nil {
|
||||
t.Fatalf("unable to get txid: %v", err)
|
||||
}
|
||||
@ -71,7 +70,7 @@ func testMultiHopPayments(net *lntest.NetworkHarness, t *harnessTest) {
|
||||
},
|
||||
)
|
||||
networkChans = append(networkChans, chanPointDave)
|
||||
daveChanTXID, err := lnd.GetChanPointFundingTxid(chanPointDave)
|
||||
daveChanTXID, err := lnrpc.GetChanPointFundingTxid(chanPointDave)
|
||||
if err != nil {
|
||||
t.Fatalf("unable to get txid: %v", err)
|
||||
}
|
||||
@ -106,7 +105,7 @@ func testMultiHopPayments(net *lntest.NetworkHarness, t *harnessTest) {
|
||||
)
|
||||
networkChans = append(networkChans, chanPointCarol)
|
||||
|
||||
carolChanTXID, err := lnd.GetChanPointFundingTxid(chanPointCarol)
|
||||
carolChanTXID, err := lnrpc.GetChanPointFundingTxid(chanPointCarol)
|
||||
if err != nil {
|
||||
t.Fatalf("unable to get txid: %v", err)
|
||||
}
|
||||
@ -120,7 +119,7 @@ func testMultiHopPayments(net *lntest.NetworkHarness, t *harnessTest) {
|
||||
nodeNames := []string{"Alice", "Bob", "Carol", "Dave"}
|
||||
for _, chanPoint := range networkChans {
|
||||
for i, node := range nodes {
|
||||
txid, err := lnd.GetChanPointFundingTxid(chanPoint)
|
||||
txid, err := lnrpc.GetChanPointFundingTxid(chanPoint)
|
||||
if err != nil {
|
||||
t.Fatalf("unable to get txid: %v", err)
|
||||
}
|
||||
|
@ -7,7 +7,6 @@ import (
|
||||
|
||||
"github.com/btcsuite/btcd/chaincfg/chainhash"
|
||||
"github.com/btcsuite/btcd/wire"
|
||||
"github.com/lightningnetwork/lnd"
|
||||
"github.com/lightningnetwork/lnd/lncfg"
|
||||
"github.com/lightningnetwork/lnd/lnrpc"
|
||||
"github.com/lightningnetwork/lnd/lnrpc/invoicesrpc"
|
||||
@ -187,7 +186,7 @@ func testMultiHopHtlcAggregation(net *lntest.NetworkHarness, t *harnessTest,
|
||||
expectedTxes = 2
|
||||
}
|
||||
|
||||
bobFundingTxid, err := lnd.GetChanPointFundingTxid(bobChanPoint)
|
||||
bobFundingTxid, err := lnrpc.GetChanPointFundingTxid(bobChanPoint)
|
||||
require.NoError(t.t, err)
|
||||
_, err = waitForNTxsInMempool(
|
||||
net.Miner.Node, expectedTxes, minerMempoolTimeout,
|
||||
|
@ -5,7 +5,6 @@ import (
|
||||
"fmt"
|
||||
|
||||
"github.com/btcsuite/btcd/wire"
|
||||
"github.com/lightningnetwork/lnd"
|
||||
"github.com/lightningnetwork/lnd/lncfg"
|
||||
"github.com/lightningnetwork/lnd/lnrpc"
|
||||
"github.com/lightningnetwork/lnd/lnrpc/invoicesrpc"
|
||||
@ -132,7 +131,7 @@ func testMultiHopHtlcLocalChainClaim(net *lntest.NetworkHarness, t *harnessTest,
|
||||
net.Miner.Node, expectedTxes, minerMempoolTimeout,
|
||||
)
|
||||
require.NoError(t.t, err)
|
||||
bobFundingTxid, err := lnd.GetChanPointFundingTxid(bobChanPoint)
|
||||
bobFundingTxid, err := lnrpc.GetChanPointFundingTxid(bobChanPoint)
|
||||
require.NoError(t.t, err)
|
||||
carolFundingPoint := wire.OutPoint{
|
||||
Hash: *bobFundingTxid,
|
||||
|
@ -7,7 +7,6 @@ import (
|
||||
"github.com/btcsuite/btcd/chaincfg/chainhash"
|
||||
"github.com/btcsuite/btcd/wire"
|
||||
"github.com/btcsuite/btcutil"
|
||||
"github.com/lightningnetwork/lnd"
|
||||
"github.com/lightningnetwork/lnd/lncfg"
|
||||
"github.com/lightningnetwork/lnd/lnrpc"
|
||||
"github.com/lightningnetwork/lnd/lnrpc/routerrpc"
|
||||
@ -109,7 +108,7 @@ func testMultiHopHtlcLocalTimeout(net *lntest.NetworkHarness, t *harnessTest,
|
||||
expectedTxes = 2
|
||||
}
|
||||
|
||||
bobFundingTxid, err := lnd.GetChanPointFundingTxid(bobChanPoint)
|
||||
bobFundingTxid, err := lnrpc.GetChanPointFundingTxid(bobChanPoint)
|
||||
require.NoError(t.t, err)
|
||||
_, err = waitForNTxsInMempool(
|
||||
net.Miner.Node, expectedTxes, minerMempoolTimeout,
|
||||
|
@ -5,7 +5,6 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/btcsuite/btcd/wire"
|
||||
"github.com/lightningnetwork/lnd"
|
||||
"github.com/lightningnetwork/lnd/lncfg"
|
||||
"github.com/lightningnetwork/lnd/lnrpc"
|
||||
"github.com/lightningnetwork/lnd/lnrpc/invoicesrpc"
|
||||
@ -122,7 +121,7 @@ func testMultiHopReceiverChainClaim(net *lntest.NetworkHarness, t *harnessTest,
|
||||
)
|
||||
require.NoError(t.t, err)
|
||||
|
||||
bobFundingTxid, err := lnd.GetChanPointFundingTxid(bobChanPoint)
|
||||
bobFundingTxid, err := lnrpc.GetChanPointFundingTxid(bobChanPoint)
|
||||
require.NoError(t.t, err)
|
||||
|
||||
carolFundingPoint := wire.OutPoint{
|
||||
|
@ -4,7 +4,6 @@ import (
|
||||
"context"
|
||||
|
||||
"github.com/btcsuite/btcd/wire"
|
||||
"github.com/lightningnetwork/lnd"
|
||||
"github.com/lightningnetwork/lnd/lncfg"
|
||||
"github.com/lightningnetwork/lnd/lnrpc"
|
||||
"github.com/lightningnetwork/lnd/lnrpc/invoicesrpc"
|
||||
@ -160,7 +159,7 @@ func testMultiHopHtlcRemoteChainClaim(net *lntest.NetworkHarness, t *harnessTest
|
||||
net.Miner.Node, expectedTxes, minerMempoolTimeout,
|
||||
)
|
||||
require.NoError(t.t, err)
|
||||
bobFundingTxid, err := lnd.GetChanPointFundingTxid(bobChanPoint)
|
||||
bobFundingTxid, err := lnrpc.GetChanPointFundingTxid(bobChanPoint)
|
||||
require.NoError(t.t, err)
|
||||
carolFundingPoint := wire.OutPoint{
|
||||
Hash: *bobFundingTxid,
|
||||
|
@ -120,7 +120,7 @@ func getTestCaseSplitTranche() ([]*testCase, uint, uint) {
|
||||
}
|
||||
|
||||
func rpcPointToWirePoint(t *harnessTest, chanPoint *lnrpc.ChannelPoint) wire.OutPoint {
|
||||
txid, err := lnd.GetChanPointFundingTxid(chanPoint)
|
||||
txid, err := lnrpc.GetChanPointFundingTxid(chanPoint)
|
||||
if err != nil {
|
||||
t.Fatalf("unable to get txid: %v", err)
|
||||
}
|
||||
@ -179,7 +179,7 @@ func openChannelAndAssert(ctx context.Context, t *harnessTest,
|
||||
if err != nil {
|
||||
t.Fatalf("error while waiting for channel open: %v", err)
|
||||
}
|
||||
fundingTxID, err := lnd.GetChanPointFundingTxid(fundingChanPoint)
|
||||
fundingTxID, err := lnrpc.GetChanPointFundingTxid(fundingChanPoint)
|
||||
if err != nil {
|
||||
t.Fatalf("unable to get txid: %v", err)
|
||||
}
|
||||
@ -291,7 +291,7 @@ func assertChannelClosed(ctx context.Context, t *harnessTest,
|
||||
fundingChanPoint *lnrpc.ChannelPoint, anchors bool,
|
||||
closeUpdates lnrpc.Lightning_CloseChannelClient) *chainhash.Hash {
|
||||
|
||||
txid, err := lnd.GetChanPointFundingTxid(fundingChanPoint)
|
||||
txid, err := lnrpc.GetChanPointFundingTxid(fundingChanPoint)
|
||||
if err != nil {
|
||||
t.Fatalf("unable to get txid: %v", err)
|
||||
}
|
||||
@ -387,7 +387,7 @@ func assertChannelClosed(ctx context.Context, t *harnessTest,
|
||||
func waitForChannelPendingForceClose(ctx context.Context,
|
||||
node *lntest.HarnessNode, fundingChanPoint *lnrpc.ChannelPoint) error {
|
||||
|
||||
txid, err := lnd.GetChanPointFundingTxid(fundingChanPoint)
|
||||
txid, err := lnrpc.GetChanPointFundingTxid(fundingChanPoint)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -1722,7 +1722,7 @@ func testPaymentFollowingChannelOpen(net *lntest.NetworkHarness, t *harnessTest)
|
||||
|
||||
// txStr returns the string representation of the channel's funding transaction.
|
||||
func txStr(chanPoint *lnrpc.ChannelPoint) string {
|
||||
fundingTxID, err := lnd.GetChanPointFundingTxid(chanPoint)
|
||||
fundingTxID, err := lnrpc.GetChanPointFundingTxid(chanPoint)
|
||||
if err != nil {
|
||||
return ""
|
||||
}
|
||||
@ -3692,7 +3692,7 @@ func channelForceClosureTest(net *lntest.NetworkHarness, t *harnessTest,
|
||||
|
||||
// Compute the outpoint of the channel, which we will use repeatedly to
|
||||
// locate the pending channel information in the rpc responses.
|
||||
txid, err := lnd.GetChanPointFundingTxid(chanPoint)
|
||||
txid, err := lnrpc.GetChanPointFundingTxid(chanPoint)
|
||||
if err != nil {
|
||||
t.Fatalf("unable to get txid: %v", err)
|
||||
}
|
||||
@ -5171,6 +5171,308 @@ func testListChannels(net *lntest.NetworkHarness, t *harnessTest) {
|
||||
|
||||
}
|
||||
|
||||
// testUpdateChanStatus checks that calls to the UpdateChanStatus RPC update
|
||||
// the channel graph as expected, and that channel state is properly updated
|
||||
// in the presence of interleaved node disconnects / reconnects.
|
||||
func testUpdateChanStatus(net *lntest.NetworkHarness, t *harnessTest) {
|
||||
ctxb := context.Background()
|
||||
|
||||
// Create two fresh nodes and open a channel between them.
|
||||
alice, err := net.NewNode("Alice", []string{
|
||||
"--minbackoff=10s",
|
||||
"--chan-enable-timeout=1.5s",
|
||||
"--chan-disable-timeout=3s",
|
||||
"--chan-status-sample-interval=.5s",
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("unable to create new node: %v", err)
|
||||
}
|
||||
defer shutdownAndAssert(net, t, alice)
|
||||
|
||||
bob, err := net.NewNode("Bob", []string{
|
||||
"--minbackoff=10s",
|
||||
"--chan-enable-timeout=1.5s",
|
||||
"--chan-disable-timeout=3s",
|
||||
"--chan-status-sample-interval=.5s",
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("unable to create new node: %v", err)
|
||||
}
|
||||
defer shutdownAndAssert(net, t, bob)
|
||||
|
||||
// Connect Alice to Bob.
|
||||
if err := net.ConnectNodes(ctxb, alice, bob); err != nil {
|
||||
t.Fatalf("unable to connect alice to bob: %v", err)
|
||||
}
|
||||
|
||||
// Give Alice some coins so she can fund a channel.
|
||||
ctxt, _ := context.WithTimeout(ctxb, defaultTimeout)
|
||||
err = net.SendCoins(ctxt, btcutil.SatoshiPerBitcoin, alice)
|
||||
if err != nil {
|
||||
t.Fatalf("unable to send coins to alice: %v", err)
|
||||
}
|
||||
|
||||
// Open a channel with 100k satoshis between Alice and Bob with Alice
|
||||
// being the sole funder of the channel.
|
||||
chanAmt := btcutil.Amount(100000)
|
||||
ctxt, _ = context.WithTimeout(ctxb, channelOpenTimeout)
|
||||
chanPoint := openChannelAndAssert(
|
||||
ctxt, t, net, alice, bob,
|
||||
lntest.OpenChannelParams{
|
||||
Amt: chanAmt,
|
||||
},
|
||||
)
|
||||
|
||||
// Wait for Alice and Bob to receive the channel edge from the
|
||||
// funding manager.
|
||||
ctxt, _ = context.WithTimeout(ctxb, defaultTimeout)
|
||||
err = alice.WaitForNetworkChannelOpen(ctxt, chanPoint)
|
||||
if err != nil {
|
||||
t.Fatalf("alice didn't see the alice->bob channel before "+
|
||||
"timeout: %v", err)
|
||||
}
|
||||
|
||||
ctxt, _ = context.WithTimeout(ctxb, defaultTimeout)
|
||||
err = bob.WaitForNetworkChannelOpen(ctxt, chanPoint)
|
||||
if err != nil {
|
||||
t.Fatalf("bob didn't see the bob->alice channel before "+
|
||||
"timeout: %v", err)
|
||||
}
|
||||
|
||||
// Launch a node for Carol which will connect to Alice and Bob in
|
||||
// order to receive graph updates. This will ensure that the
|
||||
// channel updates are propagated throughout the network.
|
||||
carol, err := net.NewNode("Carol", nil)
|
||||
if err != nil {
|
||||
t.Fatalf("unable to create Carol's node: %v", err)
|
||||
}
|
||||
defer shutdownAndAssert(net, t, carol)
|
||||
|
||||
ctxt, _ = context.WithTimeout(ctxb, defaultTimeout)
|
||||
if err := net.ConnectNodes(ctxt, alice, carol); err != nil {
|
||||
t.Fatalf("unable to connect alice to carol: %v", err)
|
||||
}
|
||||
|
||||
ctxt, _ = context.WithTimeout(ctxb, defaultTimeout)
|
||||
if err := net.ConnectNodes(ctxt, bob, carol); err != nil {
|
||||
t.Fatalf("unable to connect bob to carol: %v", err)
|
||||
}
|
||||
|
||||
carolSub := subscribeGraphNotifications(t, ctxb, carol)
|
||||
defer close(carolSub.quit)
|
||||
|
||||
// sendReq sends an UpdateChanStatus request to the given node.
|
||||
sendReq := func(node *lntest.HarnessNode, chanPoint *lnrpc.ChannelPoint,
|
||||
action routerrpc.ChanStatusAction) {
|
||||
|
||||
req := &routerrpc.UpdateChanStatusRequest{
|
||||
ChanPoint: chanPoint,
|
||||
Action: action,
|
||||
}
|
||||
ctxt, _ = context.WithTimeout(ctxb, defaultTimeout)
|
||||
_, err = node.RouterClient.UpdateChanStatus(ctxt, req)
|
||||
if err != nil {
|
||||
t.Fatalf("unable to call UpdateChanStatus for %s's node: %v",
|
||||
node.Name(), err)
|
||||
}
|
||||
}
|
||||
|
||||
// assertEdgeDisabled ensures that a given node has the correct
|
||||
// Disabled state for a channel.
|
||||
assertEdgeDisabled := func(node *lntest.HarnessNode,
|
||||
chanPoint *lnrpc.ChannelPoint, disabled bool) {
|
||||
|
||||
var predErr error
|
||||
err = wait.Predicate(func() bool {
|
||||
req := &lnrpc.ChannelGraphRequest{
|
||||
IncludeUnannounced: true,
|
||||
}
|
||||
ctxt, _ = context.WithTimeout(ctxb, defaultTimeout)
|
||||
chanGraph, err := node.DescribeGraph(ctxt, req)
|
||||
if err != nil {
|
||||
predErr = fmt.Errorf("unable to query node %v's graph: %v", node, err)
|
||||
return false
|
||||
}
|
||||
numEdges := len(chanGraph.Edges)
|
||||
if numEdges != 1 {
|
||||
predErr = fmt.Errorf("expected to find 1 edge in the graph, found %d", numEdges)
|
||||
return false
|
||||
}
|
||||
edge := chanGraph.Edges[0]
|
||||
if edge.ChanPoint != chanPoint.GetFundingTxidStr() {
|
||||
predErr = fmt.Errorf("expected chan_point %v, got %v",
|
||||
chanPoint.GetFundingTxidStr(), edge.ChanPoint)
|
||||
}
|
||||
var policy *lnrpc.RoutingPolicy
|
||||
if node.PubKeyStr == edge.Node1Pub {
|
||||
policy = edge.Node1Policy
|
||||
} else {
|
||||
policy = edge.Node2Policy
|
||||
}
|
||||
if disabled != policy.Disabled {
|
||||
predErr = fmt.Errorf("expected policy.Disabled to be %v, "+
|
||||
"but policy was %v", disabled, policy)
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}, defaultTimeout)
|
||||
if err != nil {
|
||||
t.Fatalf("%v", predErr)
|
||||
}
|
||||
}
|
||||
|
||||
// When updating the state of the channel between Alice and Bob, we
|
||||
// should expect to see channel updates with the default routing
|
||||
// policy. The value of "Disabled" will depend on the specific
|
||||
// scenario being tested.
|
||||
expectedPolicy := &lnrpc.RoutingPolicy{
|
||||
FeeBaseMsat: int64(chainreg.DefaultBitcoinBaseFeeMSat),
|
||||
FeeRateMilliMsat: int64(chainreg.DefaultBitcoinFeeRate),
|
||||
TimeLockDelta: chainreg.DefaultBitcoinTimeLockDelta,
|
||||
MinHtlc: 1000, // default value
|
||||
MaxHtlcMsat: calculateMaxHtlc(chanAmt),
|
||||
}
|
||||
|
||||
// Initially, the channel between Alice and Bob should not be
|
||||
// disabled.
|
||||
assertEdgeDisabled(alice, chanPoint, false)
|
||||
|
||||
// Manually disable the channel and ensure that a "Disabled = true"
|
||||
// update is propagated.
|
||||
sendReq(alice, chanPoint, routerrpc.ChanStatusAction_DISABLE)
|
||||
expectedPolicy.Disabled = true
|
||||
waitForChannelUpdate(
|
||||
t, carolSub,
|
||||
[]expectedChanUpdate{
|
||||
{alice.PubKeyStr, expectedPolicy, chanPoint},
|
||||
},
|
||||
)
|
||||
|
||||
// Re-enable the channel and ensure that a "Disabled = false" update
|
||||
// is propagated.
|
||||
sendReq(alice, chanPoint, routerrpc.ChanStatusAction_ENABLE)
|
||||
expectedPolicy.Disabled = false
|
||||
waitForChannelUpdate(
|
||||
t, carolSub,
|
||||
[]expectedChanUpdate{
|
||||
{alice.PubKeyStr, expectedPolicy, chanPoint},
|
||||
},
|
||||
)
|
||||
|
||||
// Manually enabling a channel should NOT prevent subsequent
|
||||
// disconnections from automatically disabling the channel again
|
||||
// (we don't want to clutter the network with channels that are
|
||||
// falsely advertised as enabled when they don't work).
|
||||
ctxt, _ = context.WithTimeout(ctxb, defaultTimeout)
|
||||
if err := net.DisconnectNodes(ctxt, alice, bob); err != nil {
|
||||
t.Fatalf("unable to disconnect Alice from Bob: %v", err)
|
||||
}
|
||||
expectedPolicy.Disabled = true
|
||||
waitForChannelUpdate(
|
||||
t, carolSub,
|
||||
[]expectedChanUpdate{
|
||||
{alice.PubKeyStr, expectedPolicy, chanPoint},
|
||||
{bob.PubKeyStr, expectedPolicy, chanPoint},
|
||||
},
|
||||
)
|
||||
|
||||
// Reconnecting the nodes should propagate a "Disabled = false" update.
|
||||
ctxt, _ = context.WithTimeout(ctxb, defaultTimeout)
|
||||
if err := net.EnsureConnected(ctxt, alice, bob); err != nil {
|
||||
t.Fatalf("unable to reconnect Alice to Bob: %v", err)
|
||||
}
|
||||
expectedPolicy.Disabled = false
|
||||
waitForChannelUpdate(
|
||||
t, carolSub,
|
||||
[]expectedChanUpdate{
|
||||
{alice.PubKeyStr, expectedPolicy, chanPoint},
|
||||
{bob.PubKeyStr, expectedPolicy, chanPoint},
|
||||
},
|
||||
)
|
||||
|
||||
// Manually disabling the channel should prevent a subsequent
|
||||
// disconnect / reconnect from re-enabling the channel on
|
||||
// Alice's end. Note the asymmetry between manual enable and
|
||||
// manual disable!
|
||||
sendReq(alice, chanPoint, routerrpc.ChanStatusAction_DISABLE)
|
||||
|
||||
// Alice sends out the "Disabled = true" update in response to
|
||||
// the ChanStatusAction_DISABLE request.
|
||||
expectedPolicy.Disabled = true
|
||||
waitForChannelUpdate(
|
||||
t, carolSub,
|
||||
[]expectedChanUpdate{
|
||||
{alice.PubKeyStr, expectedPolicy, chanPoint},
|
||||
},
|
||||
)
|
||||
|
||||
ctxt, _ = context.WithTimeout(ctxb, defaultTimeout)
|
||||
if err := net.DisconnectNodes(ctxt, alice, bob); err != nil {
|
||||
t.Fatalf("unable to disconnect Alice from Bob: %v", err)
|
||||
}
|
||||
|
||||
// Bob sends a "Disabled = true" update upon detecting the
|
||||
// disconnect.
|
||||
expectedPolicy.Disabled = true
|
||||
waitForChannelUpdate(
|
||||
t, carolSub,
|
||||
[]expectedChanUpdate{
|
||||
{bob.PubKeyStr, expectedPolicy, chanPoint},
|
||||
},
|
||||
)
|
||||
|
||||
// Bob sends a "Disabled = false" update upon detecting the
|
||||
// reconnect.
|
||||
ctxt, _ = context.WithTimeout(ctxb, defaultTimeout)
|
||||
if err := net.EnsureConnected(ctxt, alice, bob); err != nil {
|
||||
t.Fatalf("unable to reconnect Alice to Bob: %v", err)
|
||||
}
|
||||
expectedPolicy.Disabled = false
|
||||
waitForChannelUpdate(
|
||||
t, carolSub,
|
||||
[]expectedChanUpdate{
|
||||
{bob.PubKeyStr, expectedPolicy, chanPoint},
|
||||
},
|
||||
)
|
||||
|
||||
// However, since we manually disabled the channel on Alice's end,
|
||||
// the policy on Alice's end should still be "Disabled = true". Again,
|
||||
// note the asymmetry between manual enable and manual disable!
|
||||
assertEdgeDisabled(alice, chanPoint, true)
|
||||
|
||||
ctxt, _ = context.WithTimeout(ctxb, defaultTimeout)
|
||||
if err := net.DisconnectNodes(ctxt, alice, bob); err != nil {
|
||||
t.Fatalf("unable to disconnect Alice from Bob: %v", err)
|
||||
}
|
||||
|
||||
// Bob sends a "Disabled = true" update upon detecting the
|
||||
// disconnect.
|
||||
expectedPolicy.Disabled = true
|
||||
waitForChannelUpdate(
|
||||
t, carolSub,
|
||||
[]expectedChanUpdate{
|
||||
{bob.PubKeyStr, expectedPolicy, chanPoint},
|
||||
},
|
||||
)
|
||||
|
||||
// After restoring automatic channel state management on Alice's end,
|
||||
// BOTH Alice and Bob should set the channel state back to "enabled"
|
||||
// on reconnect.
|
||||
sendReq(alice, chanPoint, routerrpc.ChanStatusAction_AUTO)
|
||||
if err := net.EnsureConnected(ctxt, alice, bob); err != nil {
|
||||
t.Fatalf("unable to reconnect Alice to Bob: %v", err)
|
||||
}
|
||||
expectedPolicy.Disabled = false
|
||||
waitForChannelUpdate(
|
||||
t, carolSub,
|
||||
[]expectedChanUpdate{
|
||||
{alice.PubKeyStr, expectedPolicy, chanPoint},
|
||||
{bob.PubKeyStr, expectedPolicy, chanPoint},
|
||||
},
|
||||
)
|
||||
assertEdgeDisabled(alice, chanPoint, false)
|
||||
}
|
||||
|
||||
func testListPayments(net *lntest.NetworkHarness, t *harnessTest) {
|
||||
ctxb := context.Background()
|
||||
|
||||
@ -5534,7 +5836,7 @@ func testSingleHopSendToRouteCase(net *lntest.NetworkHarness, t *harnessTest,
|
||||
)
|
||||
networkChans = append(networkChans, chanPointCarol)
|
||||
|
||||
carolChanTXID, err := lnd.GetChanPointFundingTxid(chanPointCarol)
|
||||
carolChanTXID, err := lnrpc.GetChanPointFundingTxid(chanPointCarol)
|
||||
if err != nil {
|
||||
t.Fatalf("unable to get txid: %v", err)
|
||||
}
|
||||
@ -5547,7 +5849,7 @@ func testSingleHopSendToRouteCase(net *lntest.NetworkHarness, t *harnessTest,
|
||||
nodes := []*lntest.HarnessNode{carol, dave}
|
||||
for _, chanPoint := range networkChans {
|
||||
for _, node := range nodes {
|
||||
txid, err := lnd.GetChanPointFundingTxid(chanPoint)
|
||||
txid, err := lnrpc.GetChanPointFundingTxid(chanPoint)
|
||||
if err != nil {
|
||||
t.Fatalf("unable to get txid: %v", err)
|
||||
}
|
||||
@ -5870,7 +6172,7 @@ func testMultiHopSendToRoute(net *lntest.NetworkHarness, t *harnessTest) {
|
||||
)
|
||||
networkChans = append(networkChans, chanPointAlice)
|
||||
|
||||
aliceChanTXID, err := lnd.GetChanPointFundingTxid(chanPointAlice)
|
||||
aliceChanTXID, err := lnrpc.GetChanPointFundingTxid(chanPointAlice)
|
||||
if err != nil {
|
||||
t.Fatalf("unable to get txid: %v", err)
|
||||
}
|
||||
@ -5905,7 +6207,7 @@ func testMultiHopSendToRoute(net *lntest.NetworkHarness, t *harnessTest) {
|
||||
},
|
||||
)
|
||||
networkChans = append(networkChans, chanPointBob)
|
||||
bobChanTXID, err := lnd.GetChanPointFundingTxid(chanPointBob)
|
||||
bobChanTXID, err := lnrpc.GetChanPointFundingTxid(chanPointBob)
|
||||
if err != nil {
|
||||
t.Fatalf("unable to get txid: %v", err)
|
||||
}
|
||||
@ -5919,7 +6221,7 @@ func testMultiHopSendToRoute(net *lntest.NetworkHarness, t *harnessTest) {
|
||||
nodeNames := []string{"Alice", "Bob", "Carol"}
|
||||
for _, chanPoint := range networkChans {
|
||||
for i, node := range nodes {
|
||||
txid, err := lnd.GetChanPointFundingTxid(chanPoint)
|
||||
txid, err := lnrpc.GetChanPointFundingTxid(chanPoint)
|
||||
if err != nil {
|
||||
t.Fatalf("unable to get txid: %v", err)
|
||||
}
|
||||
@ -6302,7 +6604,7 @@ func testPrivateChannels(net *lntest.NetworkHarness, t *harnessTest) {
|
||||
)
|
||||
networkChans = append(networkChans, chanPointAlice)
|
||||
|
||||
aliceChanTXID, err := lnd.GetChanPointFundingTxid(chanPointAlice)
|
||||
aliceChanTXID, err := lnrpc.GetChanPointFundingTxid(chanPointAlice)
|
||||
if err != nil {
|
||||
t.Fatalf("unable to get txid: %v", err)
|
||||
}
|
||||
@ -6335,7 +6637,7 @@ func testPrivateChannels(net *lntest.NetworkHarness, t *harnessTest) {
|
||||
},
|
||||
)
|
||||
networkChans = append(networkChans, chanPointDave)
|
||||
daveChanTXID, err := lnd.GetChanPointFundingTxid(chanPointDave)
|
||||
daveChanTXID, err := lnrpc.GetChanPointFundingTxid(chanPointDave)
|
||||
if err != nil {
|
||||
t.Fatalf("unable to get txid: %v", err)
|
||||
}
|
||||
@ -6370,7 +6672,7 @@ func testPrivateChannels(net *lntest.NetworkHarness, t *harnessTest) {
|
||||
)
|
||||
networkChans = append(networkChans, chanPointCarol)
|
||||
|
||||
carolChanTXID, err := lnd.GetChanPointFundingTxid(chanPointCarol)
|
||||
carolChanTXID, err := lnrpc.GetChanPointFundingTxid(chanPointCarol)
|
||||
if err != nil {
|
||||
t.Fatalf("unable to get txid: %v", err)
|
||||
}
|
||||
@ -6385,7 +6687,7 @@ func testPrivateChannels(net *lntest.NetworkHarness, t *harnessTest) {
|
||||
nodeNames := []string{"Alice", "Bob", "Carol", "Dave"}
|
||||
for _, chanPoint := range networkChans {
|
||||
for i, node := range nodes {
|
||||
txid, err := lnd.GetChanPointFundingTxid(chanPoint)
|
||||
txid, err := lnrpc.GetChanPointFundingTxid(chanPoint)
|
||||
if err != nil {
|
||||
t.Fatalf("unable to get txid: %v", err)
|
||||
}
|
||||
@ -6430,7 +6732,7 @@ func testPrivateChannels(net *lntest.NetworkHarness, t *harnessTest) {
|
||||
if err != nil {
|
||||
t.Fatalf("error while waiting for channel open: %v", err)
|
||||
}
|
||||
fundingTxID, err := lnd.GetChanPointFundingTxid(chanPointPrivate)
|
||||
fundingTxID, err := lnrpc.GetChanPointFundingTxid(chanPointPrivate)
|
||||
if err != nil {
|
||||
t.Fatalf("unable to get txid: %v", err)
|
||||
}
|
||||
@ -6876,7 +7178,7 @@ func testMultiHopOverPrivateChannels(net *lntest.NetworkHarness, t *harnessTest)
|
||||
}
|
||||
|
||||
// Retrieve Alice's funding outpoint.
|
||||
aliceChanTXID, err := lnd.GetChanPointFundingTxid(chanPointAlice)
|
||||
aliceChanTXID, err := lnrpc.GetChanPointFundingTxid(chanPointAlice)
|
||||
if err != nil {
|
||||
t.Fatalf("unable to get txid: %v", err)
|
||||
}
|
||||
@ -6925,7 +7227,7 @@ func testMultiHopOverPrivateChannels(net *lntest.NetworkHarness, t *harnessTest)
|
||||
}
|
||||
|
||||
// Retrieve Bob's funding outpoint.
|
||||
bobChanTXID, err := lnd.GetChanPointFundingTxid(chanPointBob)
|
||||
bobChanTXID, err := lnrpc.GetChanPointFundingTxid(chanPointBob)
|
||||
if err != nil {
|
||||
t.Fatalf("unable to get txid: %v", err)
|
||||
}
|
||||
@ -6980,7 +7282,7 @@ func testMultiHopOverPrivateChannels(net *lntest.NetworkHarness, t *harnessTest)
|
||||
}
|
||||
|
||||
// Retrieve Carol's funding point.
|
||||
carolChanTXID, err := lnd.GetChanPointFundingTxid(chanPointCarol)
|
||||
carolChanTXID, err := lnrpc.GetChanPointFundingTxid(chanPointCarol)
|
||||
if err != nil {
|
||||
t.Fatalf("unable to get txid: %v", err)
|
||||
}
|
||||
@ -7651,7 +7953,7 @@ func testMaxPendingChannels(net *lntest.NetworkHarness, t *harnessTest) {
|
||||
t.Fatalf("error while waiting for channel open: %v", err)
|
||||
}
|
||||
|
||||
fundingTxID, err := lnd.GetChanPointFundingTxid(fundingChanPoint)
|
||||
fundingTxID, err := lnrpc.GetChanPointFundingTxid(fundingChanPoint)
|
||||
if err != nil {
|
||||
t.Fatalf("unable to get txid: %v", err)
|
||||
}
|
||||
@ -10529,11 +10831,11 @@ out:
|
||||
"expected %v, got %v", blockHeight+1,
|
||||
closedChan.ClosedHeight)
|
||||
}
|
||||
chanPointTxid, err := lnd.GetChanPointFundingTxid(chanPoint)
|
||||
chanPointTxid, err := lnrpc.GetChanPointFundingTxid(chanPoint)
|
||||
if err != nil {
|
||||
t.Fatalf("unable to get txid: %v", err)
|
||||
}
|
||||
closedChanTxid, err := lnd.GetChanPointFundingTxid(
|
||||
closedChanTxid, err := lnrpc.GetChanPointFundingTxid(
|
||||
closedChan.ChanPoint,
|
||||
)
|
||||
if err != nil {
|
||||
@ -11339,7 +11641,7 @@ func testSwitchCircuitPersistence(net *lntest.NetworkHarness, t *harnessTest) {
|
||||
)
|
||||
networkChans = append(networkChans, chanPointAlice)
|
||||
|
||||
aliceChanTXID, err := lnd.GetChanPointFundingTxid(chanPointAlice)
|
||||
aliceChanTXID, err := lnrpc.GetChanPointFundingTxid(chanPointAlice)
|
||||
if err != nil {
|
||||
t.Fatalf("unable to get txid: %v", err)
|
||||
}
|
||||
@ -11379,7 +11681,7 @@ func testSwitchCircuitPersistence(net *lntest.NetworkHarness, t *harnessTest) {
|
||||
},
|
||||
)
|
||||
networkChans = append(networkChans, chanPointDave)
|
||||
daveChanTXID, err := lnd.GetChanPointFundingTxid(chanPointDave)
|
||||
daveChanTXID, err := lnrpc.GetChanPointFundingTxid(chanPointDave)
|
||||
if err != nil {
|
||||
t.Fatalf("unable to get txid: %v", err)
|
||||
}
|
||||
@ -11416,7 +11718,7 @@ func testSwitchCircuitPersistence(net *lntest.NetworkHarness, t *harnessTest) {
|
||||
)
|
||||
networkChans = append(networkChans, chanPointCarol)
|
||||
|
||||
carolChanTXID, err := lnd.GetChanPointFundingTxid(chanPointCarol)
|
||||
carolChanTXID, err := lnrpc.GetChanPointFundingTxid(chanPointCarol)
|
||||
if err != nil {
|
||||
t.Fatalf("unable to get txid: %v", err)
|
||||
}
|
||||
@ -11430,7 +11732,7 @@ func testSwitchCircuitPersistence(net *lntest.NetworkHarness, t *harnessTest) {
|
||||
nodeNames := []string{"Alice", "Bob", "Carol", "Dave"}
|
||||
for _, chanPoint := range networkChans {
|
||||
for i, node := range nodes {
|
||||
txid, err := lnd.GetChanPointFundingTxid(chanPoint)
|
||||
txid, err := lnrpc.GetChanPointFundingTxid(chanPoint)
|
||||
if err != nil {
|
||||
t.Fatalf("unable to get txid: %v", err)
|
||||
}
|
||||
@ -11659,7 +11961,7 @@ func testSwitchOfflineDelivery(net *lntest.NetworkHarness, t *harnessTest) {
|
||||
)
|
||||
networkChans = append(networkChans, chanPointAlice)
|
||||
|
||||
aliceChanTXID, err := lnd.GetChanPointFundingTxid(chanPointAlice)
|
||||
aliceChanTXID, err := lnrpc.GetChanPointFundingTxid(chanPointAlice)
|
||||
if err != nil {
|
||||
t.Fatalf("unable to get txid: %v", err)
|
||||
}
|
||||
@ -11699,7 +12001,7 @@ func testSwitchOfflineDelivery(net *lntest.NetworkHarness, t *harnessTest) {
|
||||
},
|
||||
)
|
||||
networkChans = append(networkChans, chanPointDave)
|
||||
daveChanTXID, err := lnd.GetChanPointFundingTxid(chanPointDave)
|
||||
daveChanTXID, err := lnrpc.GetChanPointFundingTxid(chanPointDave)
|
||||
if err != nil {
|
||||
t.Fatalf("unable to get txid: %v", err)
|
||||
}
|
||||
@ -11736,7 +12038,7 @@ func testSwitchOfflineDelivery(net *lntest.NetworkHarness, t *harnessTest) {
|
||||
)
|
||||
networkChans = append(networkChans, chanPointCarol)
|
||||
|
||||
carolChanTXID, err := lnd.GetChanPointFundingTxid(chanPointCarol)
|
||||
carolChanTXID, err := lnrpc.GetChanPointFundingTxid(chanPointCarol)
|
||||
if err != nil {
|
||||
t.Fatalf("unable to get txid: %v", err)
|
||||
}
|
||||
@ -11750,7 +12052,7 @@ func testSwitchOfflineDelivery(net *lntest.NetworkHarness, t *harnessTest) {
|
||||
nodeNames := []string{"Alice", "Bob", "Carol", "Dave"}
|
||||
for _, chanPoint := range networkChans {
|
||||
for i, node := range nodes {
|
||||
txid, err := lnd.GetChanPointFundingTxid(chanPoint)
|
||||
txid, err := lnrpc.GetChanPointFundingTxid(chanPoint)
|
||||
if err != nil {
|
||||
t.Fatalf("unable to get txid: %v", err)
|
||||
}
|
||||
@ -11980,7 +12282,7 @@ func testSwitchOfflineDeliveryPersistence(net *lntest.NetworkHarness, t *harness
|
||||
)
|
||||
networkChans = append(networkChans, chanPointAlice)
|
||||
|
||||
aliceChanTXID, err := lnd.GetChanPointFundingTxid(chanPointAlice)
|
||||
aliceChanTXID, err := lnrpc.GetChanPointFundingTxid(chanPointAlice)
|
||||
if err != nil {
|
||||
t.Fatalf("unable to get txid: %v", err)
|
||||
}
|
||||
@ -12021,7 +12323,7 @@ func testSwitchOfflineDeliveryPersistence(net *lntest.NetworkHarness, t *harness
|
||||
)
|
||||
|
||||
networkChans = append(networkChans, chanPointDave)
|
||||
daveChanTXID, err := lnd.GetChanPointFundingTxid(chanPointDave)
|
||||
daveChanTXID, err := lnrpc.GetChanPointFundingTxid(chanPointDave)
|
||||
if err != nil {
|
||||
t.Fatalf("unable to get txid: %v", err)
|
||||
}
|
||||
@ -12058,7 +12360,7 @@ func testSwitchOfflineDeliveryPersistence(net *lntest.NetworkHarness, t *harness
|
||||
)
|
||||
networkChans = append(networkChans, chanPointCarol)
|
||||
|
||||
carolChanTXID, err := lnd.GetChanPointFundingTxid(chanPointCarol)
|
||||
carolChanTXID, err := lnrpc.GetChanPointFundingTxid(chanPointCarol)
|
||||
if err != nil {
|
||||
t.Fatalf("unable to get txid: %v", err)
|
||||
}
|
||||
@ -12072,7 +12374,7 @@ func testSwitchOfflineDeliveryPersistence(net *lntest.NetworkHarness, t *harness
|
||||
nodeNames := []string{"Alice", "Bob", "Carol", "Dave"}
|
||||
for _, chanPoint := range networkChans {
|
||||
for i, node := range nodes {
|
||||
txid, err := lnd.GetChanPointFundingTxid(chanPoint)
|
||||
txid, err := lnrpc.GetChanPointFundingTxid(chanPoint)
|
||||
if err != nil {
|
||||
t.Fatalf("unable to get txid: %v", err)
|
||||
}
|
||||
@ -12313,7 +12615,7 @@ func testSwitchOfflineDeliveryOutgoingOffline(
|
||||
)
|
||||
networkChans = append(networkChans, chanPointAlice)
|
||||
|
||||
aliceChanTXID, err := lnd.GetChanPointFundingTxid(chanPointAlice)
|
||||
aliceChanTXID, err := lnrpc.GetChanPointFundingTxid(chanPointAlice)
|
||||
if err != nil {
|
||||
t.Fatalf("unable to get txid: %v", err)
|
||||
}
|
||||
@ -12353,7 +12655,7 @@ func testSwitchOfflineDeliveryOutgoingOffline(
|
||||
},
|
||||
)
|
||||
networkChans = append(networkChans, chanPointDave)
|
||||
daveChanTXID, err := lnd.GetChanPointFundingTxid(chanPointDave)
|
||||
daveChanTXID, err := lnrpc.GetChanPointFundingTxid(chanPointDave)
|
||||
if err != nil {
|
||||
t.Fatalf("unable to get txid: %v", err)
|
||||
}
|
||||
@ -12388,7 +12690,7 @@ func testSwitchOfflineDeliveryOutgoingOffline(
|
||||
)
|
||||
networkChans = append(networkChans, chanPointCarol)
|
||||
|
||||
carolChanTXID, err := lnd.GetChanPointFundingTxid(chanPointCarol)
|
||||
carolChanTXID, err := lnrpc.GetChanPointFundingTxid(chanPointCarol)
|
||||
if err != nil {
|
||||
t.Fatalf("unable to get txid: %v", err)
|
||||
}
|
||||
@ -12402,7 +12704,7 @@ func testSwitchOfflineDeliveryOutgoingOffline(
|
||||
nodeNames := []string{"Alice", "Bob", "Carol", "Dave"}
|
||||
for _, chanPoint := range networkChans {
|
||||
for i, node := range nodes {
|
||||
txid, err := lnd.GetChanPointFundingTxid(chanPoint)
|
||||
txid, err := lnrpc.GetChanPointFundingTxid(chanPoint)
|
||||
if err != nil {
|
||||
t.Fatalf("unable to get txid: %v", err)
|
||||
}
|
||||
@ -12643,7 +12945,7 @@ func testQueryRoutes(net *lntest.NetworkHarness, t *harnessTest) {
|
||||
nodeNames := []string{"Alice", "Bob", "Carol", "Dave"}
|
||||
for _, chanPoint := range networkChans {
|
||||
for i, node := range nodes {
|
||||
txid, err := lnd.GetChanPointFundingTxid(chanPoint)
|
||||
txid, err := lnrpc.GetChanPointFundingTxid(chanPoint)
|
||||
if err != nil {
|
||||
t.Fatalf("unable to get txid: %v", err)
|
||||
}
|
||||
@ -12904,7 +13206,7 @@ func testRouteFeeCutoff(net *lntest.NetworkHarness, t *harnessTest) {
|
||||
}
|
||||
for _, chanPoint := range networkChans {
|
||||
for i, node := range nodes {
|
||||
txid, err := lnd.GetChanPointFundingTxid(chanPoint)
|
||||
txid, err := lnrpc.GetChanPointFundingTxid(chanPoint)
|
||||
if err != nil {
|
||||
t.Fatalf("unable to get txid: %v", err)
|
||||
}
|
||||
@ -13345,7 +13647,7 @@ func testAbandonChannel(net *lntest.NetworkHarness, t *harnessTest) {
|
||||
chanPoint := openChannelAndAssert(
|
||||
ctxt, t, net, net.Alice, net.Bob, channelParam,
|
||||
)
|
||||
txid, err := lnd.GetChanPointFundingTxid(chanPoint)
|
||||
txid, err := lnrpc.GetChanPointFundingTxid(chanPoint)
|
||||
if err != nil {
|
||||
t.Fatalf("unable to get txid: %v", err)
|
||||
}
|
||||
|
@ -71,6 +71,10 @@ var allTestCases = []*testCase{
|
||||
name: "list channels",
|
||||
test: testListChannels,
|
||||
},
|
||||
{
|
||||
name: "update channel status",
|
||||
test: testUpdateChanStatus,
|
||||
},
|
||||
{
|
||||
name: "list outgoing payments",
|
||||
test: testListPayments,
|
||||
|
@ -29,6 +29,12 @@ var (
|
||||
// the time of the request.
|
||||
ErrEnableInactiveChan = errors.New("unable to enable channel which " +
|
||||
"is not currently active")
|
||||
|
||||
// ErrEnableManuallyDisabledChan signals that an automatic / background
|
||||
// request to enable a channel could not be completed because the channel
|
||||
// was manually disabled.
|
||||
ErrEnableManuallyDisabledChan = errors.New("unable to enable channel " +
|
||||
"which was manually disabled")
|
||||
)
|
||||
|
||||
// ChanStatusConfig holds parameters and resources required by the
|
||||
@ -105,6 +111,10 @@ type ChanStatusManager struct {
|
||||
// primary event loop.
|
||||
disableRequests chan statusRequest
|
||||
|
||||
// autoRequests pipes external requests to restore automatic channel
|
||||
// state management into the primary event loop.
|
||||
autoRequests chan statusRequest
|
||||
|
||||
// statusSampleTicker fires at the interval prescribed by
|
||||
// ChanStatusSampleInterval to check if channels in chanStates have
|
||||
// become inactive.
|
||||
@ -148,6 +158,7 @@ func NewChanStatusManager(cfg *ChanStatusConfig) (*ChanStatusManager, error) {
|
||||
statusSampleTicker: time.NewTicker(cfg.ChanStatusSampleInterval),
|
||||
enableRequests: make(chan statusRequest),
|
||||
disableRequests: make(chan statusRequest),
|
||||
autoRequests: make(chan statusRequest),
|
||||
quit: make(chan struct{}),
|
||||
}, nil
|
||||
}
|
||||
@ -219,20 +230,49 @@ func (m *ChanStatusManager) Stop() error {
|
||||
// channel is found to be disabled, a new announcement will be signed with the
|
||||
// disabled bit cleared and broadcast to the network.
|
||||
//
|
||||
// If the channel was manually disabled and RequestEnable is called with
|
||||
// manual = false, then the request will be ignored.
|
||||
//
|
||||
// NOTE: RequestEnable should only be called after a stable connection with the
|
||||
// channel's peer has lasted at least the ChanEnableTimeout. Failure to do so
|
||||
// may result in behavior that deviates from the expected behavior of the state
|
||||
// machine.
|
||||
func (m *ChanStatusManager) RequestEnable(outpoint wire.OutPoint) error {
|
||||
return m.submitRequest(m.enableRequests, outpoint)
|
||||
func (m *ChanStatusManager) RequestEnable(outpoint wire.OutPoint,
|
||||
manual bool) error {
|
||||
|
||||
return m.submitRequest(m.enableRequests, outpoint, manual)
|
||||
}
|
||||
|
||||
// RequestDisable submits a request to immediately disable a channel identified
|
||||
// by the provided outpoint. If the channel is already disabled, no action will
|
||||
// be taken. Otherwise, a new announcement will be signed with the disabled bit
|
||||
// set and broadcast to the network.
|
||||
func (m *ChanStatusManager) RequestDisable(outpoint wire.OutPoint) error {
|
||||
return m.submitRequest(m.disableRequests, outpoint)
|
||||
//
|
||||
// The channel state will be changed to either ChanStatusDisabled or
|
||||
// ChanStatusManuallyDisabled, depending on the passed-in value of manual. In
|
||||
// particular, note the following state transitions:
|
||||
//
|
||||
// current state | manual | new state
|
||||
// ---------------------------------------------------
|
||||
// Disabled | false | Disabled
|
||||
// ManuallyDisabled | false | ManuallyDisabled (*)
|
||||
// Disabled | true | ManuallyDisabled
|
||||
// ManuallyDisabled | true | ManuallyDisabled
|
||||
//
|
||||
// (*) If a channel was manually disabled, subsequent automatic / background
|
||||
// requests to disable the channel do not change the fact that the channel
|
||||
// was manually disabled.
|
||||
func (m *ChanStatusManager) RequestDisable(outpoint wire.OutPoint,
|
||||
manual bool) error {
|
||||
|
||||
return m.submitRequest(m.disableRequests, outpoint, manual)
|
||||
}
|
||||
|
||||
// RequestAuto submits a request to restore automatic channel state management.
|
||||
// If the channel is in the state ChanStatusManuallyDisabled, it will be moved
|
||||
// back to the state ChanStatusDisabled. Otherwise, no action will be taken.
|
||||
func (m *ChanStatusManager) RequestAuto(outpoint wire.OutPoint) error {
|
||||
return m.submitRequest(m.autoRequests, outpoint, true)
|
||||
}
|
||||
|
||||
// statusRequest is passed to the statusManager to request a change in status
|
||||
@ -240,6 +280,7 @@ func (m *ChanStatusManager) RequestDisable(outpoint wire.OutPoint) error {
|
||||
// request through one of the enableRequests or disableRequests channels.
|
||||
type statusRequest struct {
|
||||
outpoint wire.OutPoint
|
||||
manual bool
|
||||
errChan chan error
|
||||
}
|
||||
|
||||
@ -248,10 +289,11 @@ type statusRequest struct {
|
||||
// reqChan passed in, which can be either of the enableRequests or
|
||||
// disableRequests channels.
|
||||
func (m *ChanStatusManager) submitRequest(reqChan chan statusRequest,
|
||||
outpoint wire.OutPoint) error {
|
||||
outpoint wire.OutPoint, manual bool) error {
|
||||
|
||||
req := statusRequest{
|
||||
outpoint: outpoint,
|
||||
manual: manual,
|
||||
errChan: make(chan error, 1),
|
||||
}
|
||||
|
||||
@ -285,11 +327,15 @@ func (m *ChanStatusManager) statusManager() {
|
||||
|
||||
// Process any requests to mark channel as enabled.
|
||||
case req := <-m.enableRequests:
|
||||
req.errChan <- m.processEnableRequest(req.outpoint)
|
||||
req.errChan <- m.processEnableRequest(req.outpoint, req.manual)
|
||||
|
||||
// Process any requests to mark channel as disabled.
|
||||
case req := <-m.disableRequests:
|
||||
req.errChan <- m.processDisableRequest(req.outpoint)
|
||||
req.errChan <- m.processDisableRequest(req.outpoint, req.manual)
|
||||
|
||||
// Process any requests to restore automatic channel state management.
|
||||
case req := <-m.autoRequests:
|
||||
req.errChan <- m.processAutoRequest(req.outpoint)
|
||||
|
||||
// Use long-polling to detect when channels become inactive.
|
||||
case <-m.statusSampleTicker.C:
|
||||
@ -311,13 +357,21 @@ func (m *ChanStatusManager) statusManager() {
|
||||
}
|
||||
}
|
||||
|
||||
// processEnableRequest attempts to enable the given outpoint. If the method
|
||||
// returns nil, the status of the channel in chanStates will be
|
||||
// ChanStatusEnabled. If the channel is not active at the time of the request,
|
||||
// ErrEnableInactiveChan will be returned. An update will be broadcast only if
|
||||
// the channel is currently disabled, otherwise no update will be sent on the
|
||||
// network.
|
||||
func (m *ChanStatusManager) processEnableRequest(outpoint wire.OutPoint) error {
|
||||
// processEnableRequest attempts to enable the given outpoint.
|
||||
//
|
||||
// * If the channel is not active at the time of the request,
|
||||
// ErrEnableInactiveChan will be returned.
|
||||
// * If the channel was in the ManuallyDisabled state and manual = false,
|
||||
// the request will be ignored and ErrEnableManuallyDisabledChan will be
|
||||
// returned.
|
||||
// * Otherwise, the status of the channel in chanStates will be
|
||||
// ChanStatusEnabled and the method will return nil.
|
||||
//
|
||||
// An update will be broadcast only if the channel is currently disabled,
|
||||
// otherwise no update will be sent on the network.
|
||||
func (m *ChanStatusManager) processEnableRequest(outpoint wire.OutPoint,
|
||||
manual bool) error {
|
||||
|
||||
curState, err := m.getOrInitChanStatus(outpoint)
|
||||
if err != nil {
|
||||
return err
|
||||
@ -343,6 +397,12 @@ func (m *ChanStatusManager) processEnableRequest(outpoint wire.OutPoint) error {
|
||||
"disable", outpoint)
|
||||
|
||||
// We'll sign a new update if the channel is still disabled.
|
||||
case ChanStatusManuallyDisabled:
|
||||
if !manual {
|
||||
return ErrEnableManuallyDisabledChan
|
||||
}
|
||||
fallthrough
|
||||
|
||||
case ChanStatusDisabled:
|
||||
log.Infof("Announcing channel(%v) enabled", outpoint)
|
||||
|
||||
@ -358,25 +418,22 @@ func (m *ChanStatusManager) processEnableRequest(outpoint wire.OutPoint) error {
|
||||
}
|
||||
|
||||
// processDisableRequest attempts to disable the given outpoint. If the method
|
||||
// returns nil, the status of the channel in chanStates will be
|
||||
// ChanStatusDisabled. An update will only be sent if the channel has a status
|
||||
// other than ChanStatusEnabled, otherwise no update will be sent on the
|
||||
// network.
|
||||
func (m *ChanStatusManager) processDisableRequest(outpoint wire.OutPoint) error {
|
||||
// returns nil, the status of the channel in chanStates will be either
|
||||
// ChanStatusDisabled or ChanStatusManuallyDisabled, depending on the
|
||||
// passed-in value of manual.
|
||||
//
|
||||
// An update will only be sent if the channel has a status other than
|
||||
// ChanStatusEnabled, otherwise no update will be sent on the network.
|
||||
func (m *ChanStatusManager) processDisableRequest(outpoint wire.OutPoint,
|
||||
manual bool) error {
|
||||
|
||||
curState, err := m.getOrInitChanStatus(outpoint)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
switch curState.Status {
|
||||
|
||||
// Channel is already disabled, nothing to do.
|
||||
case ChanStatusDisabled:
|
||||
return nil
|
||||
|
||||
// We'll sign a new update disabling the channel if the current status
|
||||
// is enabled or pending-inactive.
|
||||
case ChanStatusEnabled, ChanStatusPendingDisabled:
|
||||
status := curState.Status
|
||||
if status == ChanStatusEnabled || status == ChanStatusPendingDisabled {
|
||||
log.Infof("Announcing channel(%v) disabled [requested]",
|
||||
outpoint)
|
||||
|
||||
@ -386,17 +443,44 @@ func (m *ChanStatusManager) processDisableRequest(outpoint wire.OutPoint) error
|
||||
}
|
||||
}
|
||||
|
||||
// If the disable was requested via the manager's public interface, we
|
||||
// will remove the output from our map of channel states. Typically this
|
||||
// signals that the channel is being closed, so this frees up the space
|
||||
// in the map. If for some reason the channel isn't closed, the state
|
||||
// will be repopulated on subsequent calls to RequestEnable or
|
||||
// RequestDisable via a db lookup, or on startup.
|
||||
// Typically, a request to disable a channel via the manager's public
|
||||
// interface signals that the channel is being closed.
|
||||
//
|
||||
// If we don't need to keep track of a manual request to disable the
|
||||
// channel, then we can remove the outpoint to free up space in the map
|
||||
// of channel states. If for some reason the channel isn't closed, the
|
||||
// state will be repopulated on subsequent calls to the manager's public
|
||||
// interface via a db lookup, or on startup.
|
||||
if manual {
|
||||
m.chanStates.markManuallyDisabled(outpoint)
|
||||
} else if status != ChanStatusManuallyDisabled {
|
||||
delete(m.chanStates, outpoint)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// processAutoRequest attempts to restore automatic channel state management
|
||||
// for the given outpoint. If the method returns nil, the state of the channel
|
||||
// will no longer be ChanStatusManuallyDisabled (currently the only state in
|
||||
// which automatic / background requests are ignored).
|
||||
//
|
||||
// No update will be sent on the network.
|
||||
func (m *ChanStatusManager) processAutoRequest(outpoint wire.OutPoint) error {
|
||||
curState, err := m.getOrInitChanStatus(outpoint)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if curState.Status == ChanStatusManuallyDisabled {
|
||||
log.Debugf("Restoring automatic control for manually disabled "+
|
||||
"channel(%v)", outpoint)
|
||||
|
||||
m.chanStates.markDisabled(outpoint)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// markPendingInactiveChannels performs a sweep of the database's active
|
||||
// channels and determines which, if any, should have a disable announcement
|
||||
// scheduled. Once an active channel is determined to be pending-inactive, one
|
||||
|
@ -405,30 +405,48 @@ func (h *testHarness) markInactive(channels []*channeldb.OpenChannel) {
|
||||
|
||||
// assertEnables requests enables for all of the passed channels, and asserts
|
||||
// that the errors returned from RequestEnable matches expErr.
|
||||
func (h *testHarness) assertEnables(channels []*channeldb.OpenChannel, expErr error) {
|
||||
func (h *testHarness) assertEnables(channels []*channeldb.OpenChannel, expErr error,
|
||||
manual bool) {
|
||||
|
||||
h.t.Helper()
|
||||
|
||||
for _, channel := range channels {
|
||||
h.assertEnable(channel.FundingOutpoint, expErr)
|
||||
h.assertEnable(channel.FundingOutpoint, expErr, manual)
|
||||
}
|
||||
}
|
||||
|
||||
// assertDisables requests disables for all of the passed channels, and asserts
|
||||
// that the errors returned from RequestDisable matches expErr.
|
||||
func (h *testHarness) assertDisables(channels []*channeldb.OpenChannel, expErr error) {
|
||||
func (h *testHarness) assertDisables(channels []*channeldb.OpenChannel, expErr error,
|
||||
manual bool) {
|
||||
|
||||
h.t.Helper()
|
||||
|
||||
for _, channel := range channels {
|
||||
h.assertDisable(channel.FundingOutpoint, expErr)
|
||||
h.assertDisable(channel.FundingOutpoint, expErr, manual)
|
||||
}
|
||||
}
|
||||
|
||||
// assertAutos requests auto state management for all of the passed channels, and
|
||||
// asserts that the errors returned from RequestAuto matches expErr.
|
||||
func (h *testHarness) assertAutos(channels []*channeldb.OpenChannel,
|
||||
expErr error) {
|
||||
|
||||
h.t.Helper()
|
||||
|
||||
for _, channel := range channels {
|
||||
h.assertAuto(channel.FundingOutpoint, expErr)
|
||||
}
|
||||
}
|
||||
|
||||
// assertEnable requests an enable for the given outpoint, and asserts that the
|
||||
// returned error matches expErr.
|
||||
func (h *testHarness) assertEnable(outpoint wire.OutPoint, expErr error) {
|
||||
func (h *testHarness) assertEnable(outpoint wire.OutPoint, expErr error,
|
||||
manual bool) {
|
||||
|
||||
h.t.Helper()
|
||||
|
||||
err := h.mgr.RequestEnable(outpoint)
|
||||
err := h.mgr.RequestEnable(outpoint, manual)
|
||||
if err != expErr {
|
||||
h.t.Fatalf("expected enable error: %v, got %v", expErr, err)
|
||||
}
|
||||
@ -436,15 +454,28 @@ func (h *testHarness) assertEnable(outpoint wire.OutPoint, expErr error) {
|
||||
|
||||
// assertDisable requests a disable for the given outpoint, and asserts that the
|
||||
// returned error matches expErr.
|
||||
func (h *testHarness) assertDisable(outpoint wire.OutPoint, expErr error) {
|
||||
func (h *testHarness) assertDisable(outpoint wire.OutPoint, expErr error,
|
||||
manual bool) {
|
||||
|
||||
h.t.Helper()
|
||||
|
||||
err := h.mgr.RequestDisable(outpoint)
|
||||
err := h.mgr.RequestDisable(outpoint, manual)
|
||||
if err != expErr {
|
||||
h.t.Fatalf("expected disable error: %v, got %v", expErr, err)
|
||||
}
|
||||
}
|
||||
|
||||
// assertAuto requests auto state management for the given outpoint, and asserts
|
||||
// that the returned error matches expErr.
|
||||
func (h *testHarness) assertAuto(outpoint wire.OutPoint, expErr error) {
|
||||
h.t.Helper()
|
||||
|
||||
err := h.mgr.RequestAuto(outpoint)
|
||||
if err != expErr {
|
||||
h.t.Fatalf("expected error: %v, got %v", expErr, err)
|
||||
}
|
||||
}
|
||||
|
||||
// assertNoUpdates waits for the specified duration, and asserts that no updates
|
||||
// are announced on the network.
|
||||
func (h *testHarness) assertNoUpdates(duration time.Duration) {
|
||||
@ -548,7 +579,7 @@ var stateMachineTests = []stateMachineTest{
|
||||
startEnabled: false,
|
||||
fn: func(h testHarness) {
|
||||
// Request enables for all channels.
|
||||
h.assertEnables(h.graph.chans(), nil)
|
||||
h.assertEnables(h.graph.chans(), nil, false)
|
||||
// Expect to see them all enabled on the network.
|
||||
h.assertUpdates(
|
||||
h.graph.chans(), true, h.safeDisableTimeout,
|
||||
@ -561,7 +592,7 @@ var stateMachineTests = []stateMachineTest{
|
||||
startEnabled: true,
|
||||
fn: func(h testHarness) {
|
||||
// Request disables for all channels.
|
||||
h.assertDisables(h.graph.chans(), nil)
|
||||
h.assertDisables(h.graph.chans(), nil, false)
|
||||
// Expect to see them all disabled on the network.
|
||||
h.assertUpdates(
|
||||
h.graph.chans(), false, h.safeDisableTimeout,
|
||||
@ -574,7 +605,7 @@ var stateMachineTests = []stateMachineTest{
|
||||
startEnabled: true,
|
||||
fn: func(h testHarness) {
|
||||
// Request enables for already enabled channels.
|
||||
h.assertEnables(h.graph.chans(), nil)
|
||||
h.assertEnables(h.graph.chans(), nil, false)
|
||||
// Manager shouldn't send out any updates.
|
||||
h.assertNoUpdates(h.safeDisableTimeout)
|
||||
},
|
||||
@ -585,7 +616,7 @@ var stateMachineTests = []stateMachineTest{
|
||||
startEnabled: false,
|
||||
fn: func(h testHarness) {
|
||||
// Request disables for already enabled channels.
|
||||
h.assertDisables(h.graph.chans(), nil)
|
||||
h.assertDisables(h.graph.chans(), nil, false)
|
||||
// Manager shouldn't sent out any updates.
|
||||
h.assertNoUpdates(h.safeDisableTimeout)
|
||||
},
|
||||
@ -616,7 +647,7 @@ var stateMachineTests = []stateMachineTest{
|
||||
// Simulate reconnect by making channels active.
|
||||
h.markActive(h.graph.chans())
|
||||
// Request that all channels be reenabled.
|
||||
h.assertEnables(h.graph.chans(), nil)
|
||||
h.assertEnables(h.graph.chans(), nil, false)
|
||||
// Pending disable should have been canceled, and
|
||||
// no updates sent. Channels remain enabled on the
|
||||
// network.
|
||||
@ -642,7 +673,7 @@ var stateMachineTests = []stateMachineTest{
|
||||
// Request enable of inactive channels, expect error
|
||||
// indicating that channel was not active.
|
||||
h.assertEnables(
|
||||
h.graph.chans(), netann.ErrEnableInactiveChan,
|
||||
h.graph.chans(), netann.ErrEnableInactiveChan, false,
|
||||
)
|
||||
// No updates should be sent as a result of the failure.
|
||||
h.assertNoUpdates(h.safeDisableTimeout)
|
||||
@ -662,7 +693,7 @@ var stateMachineTests = []stateMachineTest{
|
||||
// Request that they be enabled, which should return an
|
||||
// error as the graph doesn't have an edge for them.
|
||||
h.assertEnables(
|
||||
unknownChans, channeldb.ErrEdgeNotFound,
|
||||
unknownChans, channeldb.ErrEdgeNotFound, false,
|
||||
)
|
||||
// No updates should be sent as a result of the failure.
|
||||
h.assertNoUpdates(h.safeDisableTimeout)
|
||||
@ -682,7 +713,7 @@ var stateMachineTests = []stateMachineTest{
|
||||
// Request that they be disabled, which should return an
|
||||
// error as the graph doesn't have an edge for them.
|
||||
h.assertDisables(
|
||||
unknownChans, channeldb.ErrEdgeNotFound,
|
||||
unknownChans, channeldb.ErrEdgeNotFound, false,
|
||||
)
|
||||
// No updates should be sent as a result of the failure.
|
||||
h.assertNoUpdates(h.safeDisableTimeout)
|
||||
@ -712,7 +743,7 @@ var stateMachineTests = []stateMachineTest{
|
||||
|
||||
// Check that trying to enable the channel with unknown
|
||||
// edges results in a failure.
|
||||
h.assertEnables(newChans, channeldb.ErrEdgeNotFound)
|
||||
h.assertEnables(newChans, channeldb.ErrEdgeNotFound, false)
|
||||
|
||||
// Now, insert edge policies for the channel into the
|
||||
// graph, starting with the channel enabled, and mark
|
||||
@ -731,7 +762,7 @@ var stateMachineTests = []stateMachineTest{
|
||||
|
||||
// Finally, assert that enabling the channel doesn't
|
||||
// return an error now that everything is in place.
|
||||
h.assertEnables(newChans, nil)
|
||||
h.assertEnables(newChans, nil, false)
|
||||
},
|
||||
},
|
||||
{
|
||||
@ -759,7 +790,7 @@ var stateMachineTests = []stateMachineTest{
|
||||
|
||||
// Check that trying to enable the channel with unknown
|
||||
// edges results in a failure.
|
||||
h.assertDisables(rmChans, channeldb.ErrEdgeNotFound)
|
||||
h.assertDisables(rmChans, channeldb.ErrEdgeNotFound, false)
|
||||
},
|
||||
},
|
||||
{
|
||||
@ -777,7 +808,7 @@ var stateMachineTests = []stateMachineTest{
|
||||
|
||||
// Check that trying to enable the channel with unknown
|
||||
// edges results in a failure.
|
||||
h.assertDisables(rmChans, nil)
|
||||
h.assertDisables(rmChans, nil, false)
|
||||
|
||||
// Since the channels are still in the graph, we expect
|
||||
// these channels to be disabled on the network.
|
||||
@ -791,6 +822,86 @@ var stateMachineTests = []stateMachineTest{
|
||||
h.assertNoUpdates(h.safeDisableTimeout)
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "request manual enable",
|
||||
startActive: true,
|
||||
startEnabled: false,
|
||||
fn: func(h testHarness) {
|
||||
// Request manual enables for all channels.
|
||||
h.assertEnables(h.graph.chans(), nil, true)
|
||||
|
||||
// Expect to see them all enabled on the network.
|
||||
h.assertUpdates(
|
||||
h.graph.chans(), true, h.safeDisableTimeout,
|
||||
)
|
||||
|
||||
// Subsequent request disables with manual = false should succeed.
|
||||
h.assertDisables(
|
||||
h.graph.chans(), nil, false,
|
||||
)
|
||||
|
||||
// Expect to see them all disabled on the network again.
|
||||
h.assertUpdates(
|
||||
h.graph.chans(), false, h.safeDisableTimeout,
|
||||
)
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "request manual disable",
|
||||
startActive: true,
|
||||
startEnabled: true,
|
||||
fn: func(h testHarness) {
|
||||
// Request manual disables for all channels.
|
||||
h.assertDisables(h.graph.chans(), nil, true)
|
||||
|
||||
// Expect to see them all disabled on the network.
|
||||
h.assertUpdates(
|
||||
h.graph.chans(), false, h.safeDisableTimeout,
|
||||
)
|
||||
|
||||
// Request enables with manual = false should fail.
|
||||
h.assertEnables(
|
||||
h.graph.chans(), netann.ErrEnableManuallyDisabledChan, false,
|
||||
)
|
||||
|
||||
// Request enables with manual = true should succeed.
|
||||
h.assertEnables(h.graph.chans(), nil, true)
|
||||
|
||||
// Expect to see them all enabled on the network again.
|
||||
h.assertUpdates(
|
||||
h.graph.chans(), true, h.safeDisableTimeout,
|
||||
)
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "restore auto",
|
||||
startActive: true,
|
||||
startEnabled: true,
|
||||
fn: func(h testHarness) {
|
||||
// Request manual disables for all channels.
|
||||
h.assertDisables(h.graph.chans(), nil, true)
|
||||
|
||||
// Expect to see them all disabled on the network.
|
||||
h.assertUpdates(
|
||||
h.graph.chans(), false, h.safeDisableTimeout,
|
||||
)
|
||||
|
||||
// Request enables with manual = false should fail.
|
||||
h.assertEnables(
|
||||
h.graph.chans(), netann.ErrEnableManuallyDisabledChan, false,
|
||||
)
|
||||
|
||||
// Request enables with manual = false should succeed after
|
||||
// restoring auto state management.
|
||||
h.assertAutos(h.graph.chans(), nil)
|
||||
h.assertEnables(h.graph.chans(), nil, false)
|
||||
|
||||
// Expect to see them all enabled on the network again.
|
||||
h.assertUpdates(
|
||||
h.graph.chans(), true, h.safeDisableTimeout,
|
||||
)
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
// TestChanStatusManagerStateMachine tests the possible state transitions that
|
||||
|
@ -26,6 +26,18 @@ const (
|
||||
// ChanStatusDisabled indicates that the channel's last announcement has
|
||||
// the disabled bit set.
|
||||
ChanStatusDisabled
|
||||
|
||||
// ChanStatusManuallyDisabled indicates that the channel's last
|
||||
// announcement had the disabled bit set, and that a user manually
|
||||
// requested disabling the channel. Channels in this state will ignore
|
||||
// automatic / background attempts to re-enable the channel.
|
||||
//
|
||||
// Note that there's no corresponding ChanStatusManuallyEnabled state
|
||||
// because even if a user manually requests enabling a channel, we still
|
||||
// DO want to allow automatic / background processes to disable it.
|
||||
// Otherwise, the network might be cluttered with channels that are
|
||||
// advertised as enabled, but don't actually work or even exist.
|
||||
ChanStatusManuallyDisabled
|
||||
)
|
||||
|
||||
// ChannelState describes the ChanStatusManager's view of a channel, and
|
||||
@ -63,6 +75,14 @@ func (s *channelStates) markDisabled(outpoint wire.OutPoint) {
|
||||
}
|
||||
}
|
||||
|
||||
// markManuallyDisabled creates a channelState using
|
||||
// ChanStatusManuallyDisabled.
|
||||
func (s *channelStates) markManuallyDisabled(outpoint wire.OutPoint) {
|
||||
(*s)[outpoint] = ChannelState{
|
||||
Status: ChanStatusManuallyDisabled,
|
||||
}
|
||||
}
|
||||
|
||||
// markPendingDisabled creates a channelState using ChanStatusPendingDisabled
|
||||
// and sets the ChannelState's SendDisableTime to sendDisableTime.
|
||||
func (s *channelStates) markPendingDisabled(outpoint wire.OutPoint,
|
||||
|
@ -2285,8 +2285,11 @@ func (p *Brontide) reenableActiveChannels() {
|
||||
// disabled bit to false and send out a new ChannelUpdate. If this
|
||||
// channel is already active, the update won't be sent.
|
||||
for _, chanPoint := range activePublicChans {
|
||||
err := p.cfg.ChanStatusMgr.RequestEnable(chanPoint)
|
||||
if err != nil {
|
||||
err := p.cfg.ChanStatusMgr.RequestEnable(chanPoint, false)
|
||||
if err == netann.ErrEnableManuallyDisabledChan {
|
||||
peerLog.Debugf("Channel(%v) was manually disabled, ignoring "+
|
||||
"automatic enable request", chanPoint)
|
||||
} else if err != nil {
|
||||
peerLog.Errorf("Unable to enable channel %v: %v",
|
||||
chanPoint, err)
|
||||
}
|
||||
@ -2360,7 +2363,9 @@ func (p *Brontide) fetchActiveChanCloser(chanID lnwire.ChannelID) (
|
||||
Channel: channel,
|
||||
UnregisterChannel: p.cfg.Switch.RemoveLink,
|
||||
BroadcastTx: p.cfg.Wallet.PublishTransaction,
|
||||
DisableChannel: p.cfg.ChanStatusMgr.RequestDisable,
|
||||
DisableChannel: func(chanPoint wire.OutPoint) error {
|
||||
return p.cfg.ChanStatusMgr.RequestDisable(chanPoint, false)
|
||||
},
|
||||
Disconnect: func() error {
|
||||
return p.cfg.DisconnectPeer(p.IdentityKey())
|
||||
},
|
||||
@ -2476,7 +2481,9 @@ func (p *Brontide) handleLocalCloseReq(req *htlcswitch.ChanClose) {
|
||||
Channel: channel,
|
||||
UnregisterChannel: p.cfg.Switch.RemoveLink,
|
||||
BroadcastTx: p.cfg.Wallet.PublishTransaction,
|
||||
DisableChannel: p.cfg.ChanStatusMgr.RequestDisable,
|
||||
DisableChannel: func(chanPoint wire.OutPoint) error {
|
||||
return p.cfg.ChanStatusMgr.RequestDisable(chanPoint, false)
|
||||
},
|
||||
Disconnect: func() error {
|
||||
return p.cfg.DisconnectPeer(p.IdentityKey())
|
||||
},
|
||||
|
42
rpcserver.go
42
rpcserver.go
@ -602,6 +602,13 @@ func newRPCServer(cfg *Config, s *server, macService *macaroons.Service,
|
||||
DefaultFinalCltvDelta: uint16(cfg.Bitcoin.TimeLockDelta),
|
||||
SubscribeHtlcEvents: s.htlcNotifier.SubscribeHtlcEvents,
|
||||
InterceptableForwarder: s.interceptableSwitch,
|
||||
SetChannelEnabled: func(outpoint wire.OutPoint) error {
|
||||
return s.chanStatusMgr.RequestEnable(outpoint, true)
|
||||
},
|
||||
SetChannelDisabled: func(outpoint wire.OutPoint) error {
|
||||
return s.chanStatusMgr.RequestDisable(outpoint, true)
|
||||
},
|
||||
SetChannelAuto: s.chanStatusMgr.RequestAuto,
|
||||
}
|
||||
|
||||
genInvoiceFeatures := func() *lnwire.FeatureVector {
|
||||
@ -1730,7 +1737,7 @@ func newFundingShimAssembler(chanPointShim *lnrpc.ChanPointShim, initiator bool,
|
||||
|
||||
// First, we'll map the RPC's channel point to one we can actually use.
|
||||
index := chanPointShim.ChanPoint.OutputIndex
|
||||
txid, err := GetChanPointFundingTxid(chanPointShim.ChanPoint)
|
||||
txid, err := lnrpc.GetChanPointFundingTxid(chanPointShim.ChanPoint)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -2079,7 +2086,7 @@ out:
|
||||
update, ok := fundingUpdate.Update.(*lnrpc.OpenStatusUpdate_ChanOpen)
|
||||
if ok {
|
||||
chanPoint := update.ChanOpen.ChannelPoint
|
||||
txid, err := GetChanPointFundingTxid(chanPoint)
|
||||
txid, err := lnrpc.GetChanPointFundingTxid(chanPoint)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -2147,29 +2154,6 @@ func (r *rpcServer) OpenChannelSync(ctx context.Context,
|
||||
}
|
||||
}
|
||||
|
||||
// GetChanPointFundingTxid returns the given channel point's funding txid in
|
||||
// raw bytes.
|
||||
func GetChanPointFundingTxid(chanPoint *lnrpc.ChannelPoint) (*chainhash.Hash, error) {
|
||||
var txid []byte
|
||||
|
||||
// A channel point's funding txid can be get/set as a byte slice or a
|
||||
// string. In the case it is a string, decode it.
|
||||
switch chanPoint.GetFundingTxid().(type) {
|
||||
case *lnrpc.ChannelPoint_FundingTxidBytes:
|
||||
txid = chanPoint.GetFundingTxidBytes()
|
||||
case *lnrpc.ChannelPoint_FundingTxidStr:
|
||||
s := chanPoint.GetFundingTxidStr()
|
||||
h, err := chainhash.NewHashFromStr(s)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
txid = h[:]
|
||||
}
|
||||
|
||||
return chainhash.NewHash(txid)
|
||||
}
|
||||
|
||||
// CloseChannel attempts to close an active channel identified by its channel
|
||||
// point. The actions of this method can additionally be augmented to attempt
|
||||
// a force close after a timeout period in the case of an inactive peer.
|
||||
@ -2194,7 +2178,7 @@ func (r *rpcServer) CloseChannel(in *lnrpc.CloseChannelRequest,
|
||||
|
||||
force := in.Force
|
||||
index := in.ChannelPoint.OutputIndex
|
||||
txid, err := GetChanPointFundingTxid(in.GetChannelPoint())
|
||||
txid, err := lnrpc.GetChanPointFundingTxid(in.GetChannelPoint())
|
||||
if err != nil {
|
||||
rpcsLog.Errorf("[closechannel] unable to get funding txid: %v", err)
|
||||
return err
|
||||
@ -2477,7 +2461,7 @@ func (r *rpcServer) AbandonChannel(_ context.Context,
|
||||
|
||||
// We'll parse out the arguments to we can obtain the chanPoint of the
|
||||
// target channel.
|
||||
txid, err := GetChanPointFundingTxid(in.GetChannelPoint())
|
||||
txid, err := lnrpc.GetChanPointFundingTxid(in.GetChannelPoint())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -5990,7 +5974,7 @@ func (r *rpcServer) UpdateChannelPolicy(ctx context.Context,
|
||||
// Otherwise, we're targeting an individual channel by its channel
|
||||
// point.
|
||||
case *lnrpc.PolicyUpdateRequest_ChanPoint:
|
||||
txid, err := GetChanPointFundingTxid(scope.ChanPoint)
|
||||
txid, err := lnrpc.GetChanPointFundingTxid(scope.ChanPoint)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -6166,7 +6150,7 @@ func (r *rpcServer) ExportChannelBackup(ctx context.Context,
|
||||
|
||||
// First, we'll convert the lnrpc channel point into a wire.OutPoint
|
||||
// that we can manipulate.
|
||||
txid, err := GetChanPointFundingTxid(in.ChanPoint)
|
||||
txid, err := lnrpc.GetChanPointFundingTxid(in.ChanPoint)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -965,7 +965,9 @@ func newServer(cfg *Config, listenAddrs []net.Addr,
|
||||
return ErrServerShuttingDown
|
||||
}
|
||||
},
|
||||
DisableChannel: s.chanStatusMgr.RequestDisable,
|
||||
DisableChannel: func(chanPoint wire.OutPoint) error {
|
||||
return s.chanStatusMgr.RequestDisable(chanPoint, false)
|
||||
},
|
||||
Sweeper: s.sweeper,
|
||||
Registry: s.invoices,
|
||||
NotifyClosedChannel: s.channelNotifier.NotifyClosedChannelEvent,
|
||||
|
Loading…
Reference in New Issue
Block a user