lncli: Make output of lncli sane and readable

LIGHT-133, LIGHT-138 Make output of `lncli showrouting table` in
two different formats: table and json.
Instead of sending serialized routing table send list of channels.
This commit is contained in:
BitfuryLightning 2016-08-20 16:49:35 -04:00
parent d764493d25
commit b5f07ede46
5 changed files with 272 additions and 109 deletions

@ -13,6 +13,9 @@ import (
"github.com/roasbeef/btcd/wire" "github.com/roasbeef/btcd/wire"
"github.com/urfave/cli" "github.com/urfave/cli"
"golang.org/x/net/context" "golang.org/x/net/context"
"github.com/BitfuryLightning/tools/rt"
"github.com/BitfuryLightning/tools/rt/graph/prefix_tree"
"github.com/BitfuryLightning/tools/rt/graph"
) )
// TODO(roasbeef): cli logic for supporting both positional and unix style // TODO(roasbeef): cli logic for supporting both positional and unix style
@ -525,6 +528,18 @@ func sendPaymentCommand(ctx *cli.Context) error {
var ShowRoutingTableCommand = cli.Command{ var ShowRoutingTableCommand = cli.Command{
Name: "showroutingtable", Name: "showroutingtable",
Description: "shows routing table for a node", Description: "shows routing table for a node",
Usage: "showroutingtable [--table]",
Flags: []cli.Flag{
cli.BoolFlag{
Name: "table",
Usage: "Show the routing table in table format. Print only a few first symbols of id",
},
cli.BoolFlag{
Name: "human",
Usage: "Simplify output to human readable form. Output lightning_id partially. Only work with --table option.",
},
},
Action: showRoutingTable, Action: showRoutingTable,
} }
@ -537,7 +552,114 @@ func showRoutingTable(ctx *cli.Context) error {
if err != nil { if err != nil {
return err return err
} }
// TODO(mkl): maybe it is better to print output directly omitting
printRespJson(resp) // conversion to RoutingTable. This part is not performance critical so
// I think it is ok because it enables code reuse
r := rt.NewRoutingTable()
for _, channel := range resp.Channels {
r.AddChannel(
graph.NewID(channel.Id1),
graph.NewID(channel.Id2),
graph.NewEdgeID(channel.EdgeID),
&rt.ChannelInfo{channel.Capacity, channel.Weight},
)
}
if err != nil {
fmt.Println("Can't unmarshall routing table")
return err
}
if ctx.Bool("table") {
printRTAsTable(r, ctx.Bool("human"))
} else {
printRTAsJSON(r)
}
return nil return nil
} }
// Prints routing table in human readable table format
func printRTAsTable(r *rt.RoutingTable, humanForm bool) {
// Minimum length of data part to which name can be shortened
var minLen int
var tmpl string
var lightningIdTree, edgeIdTree prefix_tree.PrefixTree
if humanForm {
tmpl = "%-10v %-10v %-10v %-10v %-10v\n"
minLen = 6
} else {
tmpl = "%-64v %-64v %-66v %-10v %-10v\n"
minLen = 100
}
fmt.Printf(tmpl, "ID1", "ID2", "EdgeID", "Capacity", "Weight")
channels := r.AllChannels()
if humanForm {
// Generate prefix tree for shortcuts
lightningIdTree = prefix_tree.NewPrefixTree()
for _, node := range r.Nodes() {
lightningIdTree.Add(hex.EncodeToString([]byte(node.String())))
}
edgeIdTree = prefix_tree.NewPrefixTree()
for _, channel := range channels {
edgeIdTree.Add(channel.EdgeID.String())
}
}
for _, channel := range channels {
var source, target, edgeId string
sourceHex := hex.EncodeToString([]byte(channel.Id1.String()))
targetHex := hex.EncodeToString([]byte(channel.Id2.String()))
edgeIdRaw := channel.EdgeID.String()
if humanForm {
source = getShortcut(lightningIdTree, sourceHex, minLen)
target = getShortcut(lightningIdTree, targetHex, minLen)
edgeId = getShortcut(edgeIdTree, edgeIdRaw, minLen)
} else {
source = sourceHex
target = targetHex
edgeId = edgeIdRaw
}
fmt.Printf(tmpl, source, target, edgeId, channel.Info.Cpt, channel.Info.Wgt)
}
}
func getShortcut(tree prefix_tree.PrefixTree, s string, minLen int) string {
s1, err := tree.Shortcut(s)
if err != nil || s == s1 {
return s
}
if len(s1) < minLen && minLen < len(s) {
s1 = s[:minLen]
}
shortcut := fmt.Sprintf("%v...", s1)
if len(shortcut) >= len(s) {
shortcut = s
}
return shortcut
}
func printRTAsJSON(r *rt.RoutingTable) {
type ChannelDesc struct {
ID1 string `json:"lightning_id1"`
ID2 string `json:"lightning_id2"`
EdgeId string `json:"edge_id"`
Capacity float64 `json:"capacity"`
Weight float64 `json:"weight"`
}
var channels struct {
Channels []ChannelDesc `json:"channels"`
}
channelsRaw := r.AllChannels()
channels.Channels = make([]ChannelDesc, 0, len(channelsRaw))
for _, channelRaw := range channelsRaw {
sourceHex := hex.EncodeToString([]byte(channelRaw.Id1.String()))
targetHex := hex.EncodeToString([]byte(channelRaw.Id2.String()))
channels.Channels = append(channels.Channels,
ChannelDesc{
ID1: sourceHex,
ID2: targetHex,
EdgeId: channelRaw.EdgeID.String(),
Weight: channelRaw.Info.Weight(),
Capacity: channelRaw.Info.Capacity(),
},
)
}
printRespJson(channels)
}

@ -40,6 +40,7 @@ It has these top-level messages:
PendingChannelResponse PendingChannelResponse
WalletBalanceRequest WalletBalanceRequest
WalletBalanceResponse WalletBalanceResponse
RTChannel
ShowRoutingTableRequest ShowRoutingTableRequest
ShowRoutingTableResponse ShowRoutingTableResponse
*/ */
@ -798,22 +799,42 @@ func (m *WalletBalanceResponse) String() string { return proto.Compac
func (*WalletBalanceResponse) ProtoMessage() {} func (*WalletBalanceResponse) ProtoMessage() {}
func (*WalletBalanceResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{30} } func (*WalletBalanceResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{30} }
type RTChannel struct {
Id1 string `protobuf:"bytes,1,opt,name=id1" json:"id1,omitempty"`
Id2 string `protobuf:"bytes,2,opt,name=id2" json:"id2,omitempty"`
EdgeID string `protobuf:"bytes,3,opt,name=edgeID" json:"edgeID,omitempty"`
Capacity float64 `protobuf:"fixed64,4,opt,name=capacity" json:"capacity,omitempty"`
Weight float64 `protobuf:"fixed64,5,opt,name=weight" json:"weight,omitempty"`
}
func (m *RTChannel) Reset() { *m = RTChannel{} }
func (m *RTChannel) String() string { return proto.CompactTextString(m) }
func (*RTChannel) ProtoMessage() {}
func (*RTChannel) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{31} }
type ShowRoutingTableRequest struct { type ShowRoutingTableRequest struct {
} }
func (m *ShowRoutingTableRequest) Reset() { *m = ShowRoutingTableRequest{} } func (m *ShowRoutingTableRequest) Reset() { *m = ShowRoutingTableRequest{} }
func (m *ShowRoutingTableRequest) String() string { return proto.CompactTextString(m) } func (m *ShowRoutingTableRequest) String() string { return proto.CompactTextString(m) }
func (*ShowRoutingTableRequest) ProtoMessage() {} func (*ShowRoutingTableRequest) ProtoMessage() {}
func (*ShowRoutingTableRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{31} } func (*ShowRoutingTableRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{32} }
type ShowRoutingTableResponse struct { type ShowRoutingTableResponse struct {
Rt string `protobuf:"bytes,1,opt,name=rt" json:"rt,omitempty"` Channels []*RTChannel `protobuf:"bytes,1,rep,name=channels" json:"channels,omitempty"`
} }
func (m *ShowRoutingTableResponse) Reset() { *m = ShowRoutingTableResponse{} } func (m *ShowRoutingTableResponse) Reset() { *m = ShowRoutingTableResponse{} }
func (m *ShowRoutingTableResponse) String() string { return proto.CompactTextString(m) } func (m *ShowRoutingTableResponse) String() string { return proto.CompactTextString(m) }
func (*ShowRoutingTableResponse) ProtoMessage() {} func (*ShowRoutingTableResponse) ProtoMessage() {}
func (*ShowRoutingTableResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{32} } func (*ShowRoutingTableResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{33} }
func (m *ShowRoutingTableResponse) GetChannels() []*RTChannel {
if m != nil {
return m.Channels
}
return nil
}
func init() { func init() {
proto.RegisterType((*SendRequest)(nil), "lnrpc.SendRequest") proto.RegisterType((*SendRequest)(nil), "lnrpc.SendRequest")
@ -848,6 +869,7 @@ func init() {
proto.RegisterType((*PendingChannelResponse_PendingChannel)(nil), "lnrpc.PendingChannelResponse.PendingChannel") proto.RegisterType((*PendingChannelResponse_PendingChannel)(nil), "lnrpc.PendingChannelResponse.PendingChannel")
proto.RegisterType((*WalletBalanceRequest)(nil), "lnrpc.WalletBalanceRequest") proto.RegisterType((*WalletBalanceRequest)(nil), "lnrpc.WalletBalanceRequest")
proto.RegisterType((*WalletBalanceResponse)(nil), "lnrpc.WalletBalanceResponse") proto.RegisterType((*WalletBalanceResponse)(nil), "lnrpc.WalletBalanceResponse")
proto.RegisterType((*RTChannel)(nil), "lnrpc.RTChannel")
proto.RegisterType((*ShowRoutingTableRequest)(nil), "lnrpc.ShowRoutingTableRequest") proto.RegisterType((*ShowRoutingTableRequest)(nil), "lnrpc.ShowRoutingTableRequest")
proto.RegisterType((*ShowRoutingTableResponse)(nil), "lnrpc.ShowRoutingTableResponse") proto.RegisterType((*ShowRoutingTableResponse)(nil), "lnrpc.ShowRoutingTableResponse")
proto.RegisterEnum("lnrpc.ChannelStatus", ChannelStatus_name, ChannelStatus_value) proto.RegisterEnum("lnrpc.ChannelStatus", ChannelStatus_name, ChannelStatus_value)
@ -1379,99 +1401,102 @@ var _Lightning_serviceDesc = grpc.ServiceDesc{
func init() { proto.RegisterFile("rpc.proto", fileDescriptor0) } func init() { proto.RegisterFile("rpc.proto", fileDescriptor0) }
var fileDescriptor0 = []byte{ var fileDescriptor0 = []byte{
// 1496 bytes of a gzipped FileDescriptorProto // 1539 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xb4, 0x57, 0x5b, 0x6f, 0x13, 0xd7, 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xb4, 0x57, 0x5d, 0x6f, 0x1a, 0x57,
0x13, 0xc7, 0x77, 0x7b, 0x6c, 0x27, 0xf6, 0xc9, 0xcd, 0x31, 0xf0, 0xff, 0xd3, 0x15, 0xa0, 0x08, 0x13, 0xce, 0x1a, 0x30, 0x30, 0x80, 0x0d, 0xc7, 0x5f, 0x98, 0x24, 0xef, 0x9b, 0xf7, 0x28, 0x89,
0x85, 0x40, 0x4d, 0x1f, 0x10, 0xa8, 0x54, 0xc1, 0xa4, 0x84, 0x92, 0x26, 0x29, 0x0e, 0x42, 0x7d, 0xac, 0xc8, 0x71, 0x12, 0xf2, 0x5e, 0x44, 0x89, 0x9a, 0xca, 0xc1, 0x6e, 0xec, 0xc6, 0xb5, 0xdd,
0x5a, 0xad, 0xd7, 0x27, 0x78, 0xc5, 0x7a, 0x77, 0xeb, 0x73, 0x36, 0xc1, 0xfd, 0x00, 0x7d, 0xed, 0x40, 0x14, 0xf5, 0x6a, 0xb5, 0xec, 0x1e, 0x9b, 0x55, 0x96, 0x5d, 0xca, 0x1e, 0xe2, 0xd0, 0x1f,
0x6b, 0x3f, 0x44, 0x55, 0xf5, 0x3b, 0x54, 0x7d, 0xaa, 0xd4, 0xcf, 0xd4, 0x39, 0x97, 0xb5, 0xf7, 0xd0, 0xdb, 0xde, 0xf6, 0x47, 0x54, 0x55, 0xff, 0x43, 0xd5, 0xab, 0x4a, 0xfd, 0x4d, 0x9d, 0xf3,
0xe2, 0x20, 0xf5, 0xa1, 0x4f, 0xd6, 0xce, 0x99, 0x33, 0x97, 0xdf, 0xcc, 0xfc, 0xce, 0x18, 0x6a, 0xb1, 0xb0, 0x1f, 0x38, 0x52, 0x2f, 0x7a, 0x85, 0x76, 0xce, 0x9c, 0xf9, 0x78, 0x66, 0xe6, 0x39,
0xd3, 0xc0, 0xde, 0x0b, 0xa6, 0x3e, 0xf7, 0x49, 0xc9, 0xf5, 0xf0, 0xc3, 0xf8, 0x0e, 0xea, 0x03, 0x03, 0x94, 0xc7, 0x23, 0x7b, 0x6f, 0x34, 0x0e, 0x78, 0x40, 0x0a, 0x9e, 0x8f, 0x1f, 0xf4, 0x5b,
0xea, 0x8d, 0xde, 0xd0, 0x1f, 0x42, 0xca, 0x38, 0x69, 0x40, 0x71, 0x84, 0xbf, 0x9d, 0xdc, 0xad, 0xa8, 0x74, 0x99, 0xef, 0xbc, 0x65, 0xdf, 0x4f, 0x58, 0xc8, 0x49, 0x15, 0xf2, 0x0e, 0xfe, 0x36,
0xdc, 0x4e, 0x83, 0xd4, 0xa1, 0x60, 0x4d, 0x78, 0x27, 0x8f, 0x1f, 0x05, 0xb2, 0x0e, 0x8d, 0xc0, 0x8d, 0x3b, 0xc6, 0x4e, 0x95, 0x54, 0x20, 0x67, 0x0d, 0x79, 0x73, 0x09, 0x3f, 0x72, 0x64, 0x1d,
0x9a, 0x4d, 0xa8, 0xc7, 0xcd, 0xb1, 0xc5, 0xc6, 0x9d, 0x82, 0x54, 0x69, 0x43, 0xed, 0xdc, 0x62, 0xaa, 0x23, 0x6b, 0x3a, 0x64, 0x3e, 0x37, 0x07, 0x56, 0x38, 0x68, 0xe6, 0xa4, 0x4a, 0x03, 0xca,
0xdc, 0x64, 0x68, 0xa4, 0x53, 0x44, 0x51, 0xd5, 0x58, 0x81, 0x86, 0x32, 0xc9, 0x02, 0xdf, 0x63, 0x17, 0x56, 0xc8, 0xcd, 0x10, 0x8d, 0x34, 0xf3, 0x28, 0x2a, 0xd1, 0x15, 0xa8, 0x2a, 0x93, 0xe1,
0xd4, 0x78, 0x02, 0x8d, 0xfe, 0xd8, 0xf2, 0x3c, 0xea, 0x9e, 0xfa, 0x8e, 0xc7, 0x85, 0xa1, 0xf3, 0x28, 0xf0, 0x43, 0x46, 0x9f, 0x43, 0xb5, 0x33, 0xb0, 0x7c, 0x9f, 0x79, 0xe7, 0x81, 0xeb, 0x73,
0xd0, 0x1b, 0x39, 0xde, 0x7b, 0x93, 0x7f, 0x74, 0x46, 0xda, 0x17, 0x4a, 0xfd, 0x90, 0x07, 0x21, 0x61, 0xe8, 0x62, 0xe2, 0x3b, 0xae, 0x7f, 0x69, 0xf2, 0x4f, 0xae, 0xa3, 0x7d, 0xa1, 0x34, 0x98,
0x37, 0x1d, 0x6f, 0x44, 0x3f, 0x4a, 0xa7, 0x4d, 0xe3, 0x0b, 0x68, 0x1d, 0x39, 0xef, 0xc7, 0xdc, 0xf0, 0xd1, 0x84, 0x9b, 0xae, 0xef, 0xb0, 0x4f, 0xd2, 0x69, 0x8d, 0xfe, 0x1f, 0xea, 0x27, 0xee,
0x43, 0xed, 0xfd, 0xd1, 0x68, 0x4a, 0x19, 0x23, 0x04, 0x20, 0x08, 0x87, 0xaf, 0xe9, 0xec, 0x50, 0xe5, 0x80, 0xfb, 0xa8, 0xbd, 0xef, 0x38, 0x63, 0x16, 0x86, 0x84, 0x00, 0x8c, 0x26, 0xfd, 0x37,
0x84, 0x21, 0x6e, 0xd7, 0x44, 0xdc, 0x63, 0x9f, 0xa9, 0x50, 0x6b, 0xc6, 0x4f, 0x39, 0x58, 0x15, 0x6c, 0x7a, 0x24, 0xc2, 0x10, 0xb7, 0xcb, 0x22, 0xee, 0x41, 0x10, 0xaa, 0x50, 0xcb, 0xf4, 0x47,
0x21, 0x7c, 0x6b, 0x79, 0xb3, 0x28, 0xb3, 0x67, 0xd0, 0x10, 0x06, 0xce, 0xfc, 0xfd, 0x89, 0x1f, 0x03, 0x56, 0x45, 0x08, 0xdf, 0x58, 0xfe, 0x34, 0xca, 0xec, 0x25, 0x54, 0x85, 0x81, 0x5e, 0xb0,
0x7a, 0x22, 0xc3, 0xc2, 0x4e, 0xbd, 0xb7, 0xb3, 0x27, 0x61, 0xd8, 0x4b, 0x69, 0xef, 0xc5, 0x55, 0x3f, 0x0c, 0x26, 0xbe, 0xc8, 0x30, 0xb7, 0x53, 0x69, 0xef, 0xec, 0x49, 0x18, 0xf6, 0x52, 0xda,
0x0f, 0x3c, 0x3e, 0x9d, 0x75, 0x1f, 0x41, 0x3b, 0x23, 0x14, 0x00, 0x7d, 0xa0, 0x33, 0x1d, 0x43, 0x7b, 0x71, 0xd5, 0x43, 0x9f, 0x8f, 0xa7, 0xad, 0xa7, 0xd0, 0xc8, 0x08, 0x05, 0x40, 0x1f, 0xd8,
0x13, 0x4a, 0x17, 0x96, 0x1b, 0x52, 0x85, 0xd7, 0x93, 0xfc, 0xe3, 0x9c, 0x71, 0x0b, 0x5a, 0x0b, 0x54, 0xc7, 0x50, 0x83, 0xc2, 0x47, 0xcb, 0x9b, 0x30, 0x85, 0xd7, 0xf3, 0xa5, 0x67, 0x06, 0xbd,
0xcb, 0x0a, 0x0e, 0x11, 0xea, 0x3c, 0xed, 0x9a, 0xf1, 0x50, 0x69, 0xf4, 0x11, 0x19, 0x16, 0x2b, 0x03, 0xf5, 0xb9, 0x65, 0x05, 0x87, 0x08, 0x75, 0x96, 0x76, 0x99, 0x3e, 0x56, 0x1a, 0x1d, 0x44,
0x82, 0x85, 0xae, 0xb4, 0xd9, 0x15, 0x28, 0x5b, 0x2a, 0x64, 0x69, 0xd7, 0xf8, 0x0c, 0xda, 0xb1, 0x26, 0x8c, 0x15, 0xc1, 0x42, 0x57, 0xda, 0xec, 0x0a, 0x2c, 0x5b, 0x2a, 0x64, 0x69, 0x97, 0xfe,
0x1b, 0x4b, 0x8d, 0xfe, 0x92, 0x83, 0xf6, 0x31, 0xbd, 0xd4, 0x80, 0x45, 0x66, 0x7b, 0xa8, 0x33, 0x0f, 0x1a, 0xb1, 0x1b, 0x0b, 0x8d, 0xfe, 0x6c, 0x40, 0xe3, 0x94, 0x5d, 0x69, 0xc0, 0x22, 0xb3,
0x0b, 0xa8, 0xd4, 0x59, 0xe9, 0xdd, 0xd6, 0x99, 0x67, 0xf4, 0xf6, 0xf4, 0xe7, 0x19, 0xea, 0x1a, 0x6d, 0xd4, 0x99, 0x8e, 0x98, 0xd4, 0x59, 0x69, 0xdf, 0xd5, 0x99, 0x67, 0xf4, 0xf6, 0xf4, 0x67,
0x27, 0x50, 0x8f, 0x7d, 0x92, 0x2d, 0x58, 0x7b, 0xf7, 0xea, 0xec, 0xf8, 0x60, 0x30, 0x30, 0x4f, 0x0f, 0x75, 0xe9, 0x19, 0x54, 0x62, 0x9f, 0x64, 0x0b, 0xd6, 0xde, 0x1f, 0xf7, 0x4e, 0x0f, 0xbb,
0xdf, 0x3e, 0x7f, 0x7d, 0xf0, 0xbd, 0x79, 0xb8, 0x3f, 0x38, 0x6c, 0x5d, 0x23, 0x9b, 0x40, 0x50, 0x5d, 0xf3, 0xfc, 0xdd, 0xab, 0x37, 0x87, 0xdf, 0x99, 0x47, 0xfb, 0xdd, 0xa3, 0xfa, 0x0d, 0xb2,
0x7a, 0x76, 0xf0, 0x22, 0x21, 0xcf, 0x91, 0x55, 0xa8, 0xc7, 0x05, 0x79, 0xe3, 0x0e, 0x2a, 0xc6, 0x09, 0x04, 0xa5, 0xbd, 0xc3, 0x83, 0x84, 0xdc, 0x20, 0xab, 0x50, 0x89, 0x0b, 0x96, 0xe8, 0x3d,
0x3c, 0xea, 0xf0, 0x57, 0xa1, 0x62, 0x29, 0x91, 0xce, 0xe0, 0x29, 0x90, 0xbe, 0x8f, 0x2d, 0x63, 0x54, 0x8c, 0x79, 0xd4, 0xe1, 0xaf, 0x42, 0xd1, 0x52, 0x22, 0x9d, 0xc1, 0x0b, 0x20, 0x9d, 0x00,
0xf3, 0x53, 0x4a, 0xa7, 0x51, 0x06, 0x77, 0x62, 0xc0, 0xd4, 0x7b, 0x5b, 0x3a, 0x83, 0x74, 0x83, 0x5b, 0xc6, 0xe6, 0xe7, 0x8c, 0x8d, 0xa3, 0x0c, 0xee, 0xc5, 0x80, 0xa9, 0xb4, 0xb7, 0x74, 0x06,
0x18, 0x77, 0x61, 0x2d, 0x71, 0x79, 0xe1, 0x24, 0xc0, 0x6f, 0x53, 0xc3, 0x54, 0x32, 0x5e, 0x40, 0xe9, 0x06, 0xa1, 0xf7, 0x61, 0x2d, 0x71, 0x79, 0xee, 0x64, 0x84, 0xdf, 0xa6, 0x86, 0xa9, 0x40,
0xf1, 0xf0, 0xec, 0xa8, 0x8f, 0xfd, 0x94, 0xd7, 0xb2, 0x42, 0x1a, 0x6d, 0xd1, 0xdf, 0xa2, 0xdb, 0x0f, 0x20, 0x7f, 0xd4, 0x3b, 0xe9, 0x60, 0x3f, 0x2d, 0x69, 0x59, 0x2e, 0x8d, 0xb6, 0xe8, 0x6f,
0x4d, 0xd7, 0xb7, 0x3f, 0xe8, 0x96, 0xc7, 0x3a, 0x73, 0xdf, 0x0c, 0x99, 0x6e, 0xf7, 0xbf, 0x73, 0xd1, 0xed, 0xa6, 0x17, 0xd8, 0x1f, 0x74, 0xcb, 0x63, 0x9d, 0x79, 0x60, 0x4e, 0x42, 0xdd, 0xee,
0xd0, 0xdc, 0xb7, 0xb9, 0x73, 0x41, 0x75, 0x97, 0x8b, 0x3b, 0x53, 0x3a, 0xf1, 0x39, 0x8d, 0x5c, 0x7f, 0x19, 0x50, 0xdb, 0xb7, 0xb9, 0xfb, 0x91, 0xe9, 0x2e, 0x17, 0x77, 0xc6, 0x6c, 0x18, 0x70,
0xd5, 0xc8, 0x06, 0x34, 0x6d, 0x75, 0x6a, 0x06, 0x62, 0x08, 0x54, 0xa3, 0x92, 0x16, 0x54, 0x6d, 0x16, 0xb9, 0x2a, 0x93, 0x0d, 0xa8, 0xd9, 0xea, 0xd4, 0x1c, 0x89, 0x21, 0x50, 0x8d, 0x4a, 0xea,
0x2b, 0xb0, 0x6c, 0x87, 0xcf, 0xa4, 0xf1, 0x82, 0x50, 0x44, 0x57, 0x96, 0x6b, 0x0e, 0x2d, 0xd7, 0x50, 0xb2, 0xad, 0x91, 0x65, 0xbb, 0x7c, 0x2a, 0x8d, 0xe7, 0x84, 0x22, 0xba, 0xb2, 0x3c, 0xb3,
0xf2, 0x6c, 0x2a, 0x9d, 0x14, 0x10, 0xdf, 0x15, 0x6d, 0x32, 0x92, 0x97, 0xa4, 0x7c, 0x1b, 0xda, 0x6f, 0x79, 0x96, 0x6f, 0x33, 0xe9, 0x24, 0x87, 0xf8, 0xae, 0x68, 0x93, 0x91, 0xbc, 0x20, 0xe5,
0x21, 0xe6, 0xc6, 0xb9, 0x4b, 0x47, 0xe6, 0x90, 0xaa, 0xa3, 0xb2, 0x3c, 0x32, 0xa0, 0x19, 0x50, 0xdb, 0xd0, 0x98, 0x60, 0x6e, 0x9c, 0x7b, 0xcc, 0x31, 0xfb, 0x4c, 0x1d, 0x2d, 0xcb, 0x23, 0x0a,
0x35, 0x66, 0x63, 0xee, 0xda, 0xac, 0x53, 0x91, 0x1d, 0x5f, 0xd7, 0xa8, 0xc9, 0xcc, 0xd7, 0xa0, 0xb5, 0x11, 0x53, 0x63, 0x36, 0xe0, 0x9e, 0x1d, 0x36, 0x8b, 0xb2, 0xe3, 0x2b, 0x1a, 0x35, 0x99,
0xee, 0x85, 0x13, 0x33, 0x0c, 0x46, 0x16, 0xa7, 0xac, 0x53, 0xc5, 0x8b, 0x45, 0xe3, 0x8f, 0x1c, 0xf9, 0x1a, 0x54, 0xfc, 0xc9, 0xd0, 0x9c, 0x8c, 0x1c, 0x8b, 0xb3, 0xb0, 0x59, 0xc2, 0x8b, 0x79,
0x14, 0x05, 0x70, 0x62, 0x24, 0xdd, 0x08, 0xdb, 0x45, 0x2a, 0x31, 0x18, 0x45, 0x12, 0xa5, 0x78, 0xfa, 0xbb, 0x01, 0x79, 0x01, 0x9c, 0x18, 0x49, 0x2f, 0xc2, 0x76, 0x9e, 0x4a, 0x0c, 0x46, 0x91,
0xf1, 0x0a, 0x52, 0x03, 0x01, 0x1d, 0xce, 0xd0, 0x9e, 0x20, 0x05, 0x2e, 0x13, 0x28, 0x2e, 0x64, 0x44, 0x21, 0x5e, 0xbc, 0x9c, 0xd4, 0x40, 0x40, 0xfb, 0x53, 0xb4, 0x27, 0x48, 0x81, 0xcb, 0x04,
0x53, 0x6a, 0x5f, 0xc8, 0xe0, 0x8b, 0x22, 0x7b, 0x66, 0x71, 0xa5, 0xa5, 0x62, 0xd6, 0x12, 0xa9, 0xf2, 0x73, 0xd9, 0x98, 0xd9, 0x1f, 0x65, 0xf0, 0x79, 0x91, 0x7d, 0x68, 0x71, 0xa5, 0xa5, 0x62,
0x53, 0x91, 0x12, 0x34, 0xee, 0x78, 0x43, 0x2c, 0xc8, 0x48, 0x46, 0x57, 0x25, 0x77, 0x11, 0x32, 0xd6, 0x12, 0xa9, 0x53, 0x94, 0x12, 0x34, 0xee, 0xfa, 0x7d, 0x2c, 0x88, 0x23, 0xa3, 0x2b, 0x91,
0x85, 0x24, 0xeb, 0xd4, 0x64, 0x46, 0xeb, 0x3a, 0xa3, 0x44, 0x11, 0x0c, 0x22, 0x98, 0x83, 0xc9, 0xfb, 0x08, 0x99, 0x42, 0x32, 0x6c, 0x96, 0x65, 0x46, 0xeb, 0x3a, 0xa3, 0x44, 0x11, 0x28, 0x11,
0x0e, 0x88, 0x3a, 0xdb, 0x78, 0x00, 0xed, 0x98, 0x4c, 0xb7, 0x45, 0x17, 0x4a, 0x22, 0x1f, 0xa6, 0xcc, 0x11, 0xca, 0x0e, 0x88, 0x3a, 0x9b, 0x3e, 0x82, 0x46, 0x4c, 0xa6, 0xdb, 0xa2, 0x05, 0x05,
0x19, 0x21, 0xc2, 0x47, 0x28, 0x19, 0x2d, 0x58, 0x79, 0x49, 0xf9, 0x2b, 0xef, 0xdc, 0x8f, 0x4c, 0x91, 0x4f, 0xa8, 0x19, 0x21, 0xc2, 0x47, 0x28, 0xd1, 0x3a, 0xac, 0xbc, 0x66, 0xfc, 0xd8, 0xbf,
0xfc, 0x8c, 0xd4, 0x32, 0x17, 0x69, 0x0b, 0xcb, 0x71, 0xea, 0x40, 0xcb, 0x19, 0x61, 0x6a, 0x58, 0x08, 0x22, 0x13, 0x3f, 0x21, 0xb5, 0xcc, 0x44, 0xda, 0xc2, 0x62, 0x9c, 0x9a, 0x50, 0x77, 0x1d,
0x5b, 0x33, 0xc2, 0x47, 0x55, 0xfd, 0x06, 0xac, 0x0b, 0xd4, 0xa3, 0xea, 0xcc, 0xd3, 0x11, 0xe8, 0x4c, 0x0d, 0x6b, 0x6b, 0x46, 0xf8, 0xa8, 0xaa, 0xdf, 0x82, 0x75, 0x81, 0x7a, 0x54, 0x9d, 0x59,
0x35, 0xc9, 0x75, 0x58, 0x13, 0xa7, 0x96, 0xcc, 0x66, 0x71, 0x58, 0x94, 0x87, 0xd8, 0x5a, 0xea, 0x3a, 0x02, 0xbd, 0x1a, 0xb9, 0x09, 0x6b, 0xe2, 0xd4, 0x92, 0xd9, 0xcc, 0x0f, 0xf3, 0xf2, 0x10,
0xaa, 0x08, 0xb8, 0x24, 0x29, 0xf2, 0xad, 0x1c, 0x95, 0x73, 0x67, 0x3a, 0xb1, 0xb8, 0xe3, 0x7b, 0x5b, 0x4b, 0x5d, 0x15, 0x01, 0x17, 0x24, 0x45, 0xbe, 0x93, 0xa3, 0x72, 0xe1, 0x8e, 0x87, 0x16,
0x6f, 0x65, 0x2d, 0x85, 0xe2, 0x50, 0xf4, 0xac, 0xc9, 0xc6, 0xd6, 0x82, 0x61, 0x95, 0x68, 0x4c, 0x77, 0x03, 0xff, 0x9d, 0xac, 0xa5, 0x50, 0xec, 0x8b, 0x9e, 0x35, 0xc3, 0x81, 0x35, 0x67, 0x58,
0x45, 0xb4, 0xba, 0x7a, 0xd8, 0x59, 0xc2, 0xa2, 0x8d, 0x26, 0x98, 0xe9, 0xd2, 0x73, 0xae, 0xc2, 0x25, 0x1a, 0x30, 0x11, 0xad, 0xae, 0x1e, 0x76, 0x96, 0xb0, 0x68, 0xa3, 0x89, 0xd0, 0xf4, 0xd8,
0x30, 0xbe, 0x82, 0xb6, 0x86, 0xf2, 0x04, 0x03, 0xd5, 0x56, 0xef, 0xa5, 0xdb, 0x58, 0x4d, 0xe2, 0x05, 0x57, 0x61, 0xd0, 0x2f, 0xa1, 0xa1, 0xa1, 0x3c, 0xc3, 0x40, 0xb5, 0xd5, 0x07, 0xe9, 0x36,
0x9a, 0xc6, 0x2c, 0x4e, 0xf3, 0x72, 0x84, 0xd5, 0x77, 0xdf, 0xf5, 0x19, 0xd5, 0x16, 0x30, 0x08, 0x56, 0x93, 0xb8, 0xa6, 0x31, 0x8b, 0xd3, 0xbc, 0x1c, 0x61, 0xf5, 0xdd, 0xf1, 0x82, 0x90, 0x69,
0x1b, 0x3f, 0x53, 0xe4, 0x8f, 0x55, 0x66, 0xa1, 0x6d, 0x47, 0x10, 0x55, 0x8d, 0x00, 0x47, 0x58, 0x0b, 0x18, 0x84, 0x8d, 0x9f, 0x29, 0xf2, 0xc7, 0x2a, 0x87, 0x13, 0xdb, 0x8e, 0x20, 0x2a, 0xd1,
0xdc, 0xd2, 0x16, 0x22, 0x02, 0xf8, 0x17, 0xfe, 0x45, 0xc7, 0x71, 0x67, 0x42, 0x4d, 0xd7, 0x99, 0x11, 0x8e, 0xb0, 0xb8, 0xa5, 0x2d, 0x44, 0x04, 0xf0, 0x0f, 0xfc, 0x8b, 0x8e, 0xe3, 0xee, 0x90,
0x38, 0xd1, 0x34, 0xe3, 0xb8, 0x58, 0xae, 0xeb, 0x5f, 0x9a, 0xe7, 0xfe, 0xd4, 0x46, 0x70, 0x85, 0x99, 0x9e, 0x3b, 0x74, 0xa3, 0x69, 0xc6, 0x71, 0xb1, 0x3c, 0x2f, 0xb8, 0x32, 0x2f, 0x82, 0xb1,
0x0b, 0x99, 0x6f, 0xd5, 0xf8, 0x1d, 0x39, 0x53, 0xba, 0x1c, 0x70, 0x8b, 0x87, 0x4c, 0x87, 0x7b, 0x8d, 0xe0, 0x0a, 0x17, 0x32, 0xdf, 0x12, 0xfd, 0x0d, 0x39, 0x53, 0xba, 0xec, 0x72, 0x8b, 0x4f,
0x1f, 0x1d, 0x0a, 0x61, 0x54, 0x2c, 0xed, 0x70, 0x7d, 0xde, 0x24, 0x52, 0xaa, 0x94, 0x0f, 0xaf, 0x42, 0x1d, 0xee, 0x43, 0x74, 0x28, 0x84, 0x51, 0xb1, 0xb4, 0xc3, 0xf5, 0x59, 0x93, 0x48, 0xa9,
0x91, 0xcf, 0x31, 0xbb, 0x58, 0x2d, 0xa4, 0xd7, 0x7a, 0x6f, 0x3b, 0x0a, 0x2f, 0x53, 0x26, 0xbc, 0x52, 0x3e, 0xba, 0x41, 0x9e, 0x60, 0x76, 0xb1, 0x5a, 0x48, 0xaf, 0x95, 0xf6, 0x76, 0x14, 0x5e,
0xf2, 0x00, 0x40, 0xa4, 0x14, 0x8b, 0x25, 0x76, 0x21, 0x83, 0xdf, 0xe1, 0xb5, 0xe7, 0x55, 0x28, 0xa6, 0x4c, 0x78, 0xe5, 0x11, 0x80, 0x48, 0x29, 0x16, 0x4b, 0xec, 0x42, 0x06, 0xbf, 0xa3, 0x1b,
0xab, 0x79, 0x35, 0x6e, 0x42, 0x33, 0x11, 0x40, 0xe2, 0x15, 0x68, 0x88, 0x39, 0x26, 0xa2, 0x76, 0xaf, 0x4a, 0xb0, 0xac, 0xe6, 0x95, 0xde, 0x86, 0x5a, 0x22, 0x80, 0xc4, 0x2b, 0x50, 0x15, 0x73,
0x29, 0x0c, 0xb1, 0xe0, 0xdc, 0x9a, 0xbe, 0xa7, 0xdc, 0x4c, 0xb0, 0x21, 0xd9, 0x85, 0xba, 0x96, 0x4c, 0x44, 0xed, 0x52, 0x18, 0x62, 0xc1, 0xb9, 0x35, 0xbe, 0x64, 0xdc, 0x4c, 0xb0, 0x21, 0xd9,
0x7b, 0xfe, 0x88, 0xea, 0xd0, 0xaf, 0xe2, 0x58, 0xd1, 0xc3, 0x8a, 0xa7, 0xa2, 0xa7, 0x5c, 0xb3, 0x85, 0x8a, 0x96, 0xfb, 0x81, 0xc3, 0x74, 0xe8, 0xd7, 0x71, 0xac, 0xe8, 0x61, 0xc5, 0x53, 0xd1,
0xa6, 0x62, 0xb1, 0x9b, 0xb0, 0xa1, 0xe9, 0x2a, 0x75, 0xac, 0xd8, 0x6c, 0x0b, 0x56, 0x6d, 0x7f, 0x53, 0xae, 0x59, 0x53, 0xb1, 0xd8, 0x6d, 0xd8, 0xd0, 0x74, 0x95, 0x3a, 0x56, 0x6c, 0xb6, 0x05,
0x32, 0x71, 0x18, 0x43, 0x24, 0x4c, 0xe6, 0xfc, 0x18, 0xd1, 0x99, 0x6e, 0x6f, 0xd9, 0x8c, 0x92, 0xab, 0x76, 0x30, 0x1c, 0xba, 0x61, 0x88, 0x48, 0x98, 0xa1, 0xfb, 0x43, 0x44, 0x67, 0xba, 0xbd,
0x12, 0x9a, 0xc6, 0xaf, 0x39, 0x68, 0x89, 0x2c, 0x12, 0x65, 0xd9, 0x45, 0x9c, 0x05, 0x68, 0xff, 0x65, 0x33, 0x4a, 0x4a, 0xa8, 0xd1, 0x5f, 0x0c, 0xa8, 0x8b, 0x2c, 0x12, 0x65, 0xd9, 0x45, 0x9c,
0x59, 0x55, 0xee, 0x43, 0x4d, 0x3a, 0xf0, 0xd1, 0x83, 0x2e, 0x4a, 0x27, 0x59, 0x94, 0xc5, 0x54, 0x05, 0x68, 0xff, 0x5a, 0x55, 0x1e, 0x42, 0x59, 0x3a, 0x08, 0xd0, 0x83, 0x2e, 0x4a, 0x33, 0x59,
0x24, 0x6a, 0xf2, 0x25, 0x6c, 0x68, 0xf7, 0x29, 0xd8, 0x6f, 0x43, 0x99, 0xc9, 0x14, 0xf4, 0xfb, 0x94, 0xf9, 0x54, 0x24, 0x6a, 0xf2, 0x05, 0x6c, 0x68, 0xf7, 0x29, 0xd8, 0xef, 0xc2, 0x72, 0x28,
0xbb, 0x9e, 0x34, 0xa7, 0xd2, 0x33, 0x7e, 0xcb, 0xc3, 0x66, 0xfa, 0xbe, 0x66, 0x99, 0xaf, 0xa1, 0x53, 0xd0, 0xef, 0xef, 0x7a, 0xd2, 0x9c, 0x4a, 0x8f, 0xfe, 0xba, 0x04, 0x9b, 0xe9, 0xfb, 0x9a,
0x95, 0x61, 0x0c, 0x45, 0x59, 0xbb, 0xc9, 0xbc, 0x53, 0x17, 0x53, 0xe2, 0xee, 0x5f, 0x39, 0x58, 0x65, 0xbe, 0x82, 0x7a, 0x86, 0x31, 0x14, 0x65, 0xed, 0x26, 0xf3, 0x4e, 0x5d, 0x4c, 0x89, 0x5b,
0x49, 0x8a, 0x32, 0x2f, 0x63, 0x86, 0xd1, 0xf2, 0xcb, 0x1f, 0xb1, 0x42, 0xe6, 0x11, 0x2b, 0x2e, 0x7f, 0x1a, 0xb0, 0x92, 0x14, 0x65, 0x5e, 0xc6, 0x0c, 0xa3, 0x2d, 0x2d, 0x7e, 0xc4, 0x72, 0x99,
0x7f, 0xc4, 0x4a, 0x57, 0x3c, 0x62, 0xe5, 0x68, 0xb3, 0x4c, 0x70, 0x42, 0x45, 0x9a, 0x5d, 0x00, 0x47, 0x2c, 0xbf, 0xf8, 0x11, 0x2b, 0x5c, 0xf3, 0x88, 0x2d, 0x47, 0x9b, 0x65, 0x82, 0x13, 0x8a,
0x56, 0xfd, 0x04, 0x60, 0xbb, 0xb0, 0xfe, 0x0e, 0x47, 0x9a, 0xf2, 0xe7, 0xca, 0x64, 0x04, 0x37, 0xd2, 0xec, 0x1c, 0xb0, 0xd2, 0x67, 0x00, 0xdb, 0x85, 0xf5, 0xf7, 0x38, 0xd2, 0x8c, 0xbf, 0x52,
0xda, 0xbc, 0x74, 0xb8, 0x87, 0xad, 0x6a, 0xfa, 0x9e, 0xab, 0x56, 0xb4, 0xaa, 0xb1, 0x03, 0x1b, 0x26, 0x23, 0xb8, 0xd1, 0xe6, 0x95, 0xcb, 0x7d, 0x6c, 0x55, 0x33, 0xf0, 0x3d, 0xb5, 0xa2, 0x95,
0x29, 0xed, 0xc5, 0x6e, 0x10, 0xc5, 0x24, 0x34, 0x73, 0xc6, 0x36, 0x6c, 0x0d, 0xc6, 0xfe, 0xe5, 0xe8, 0x0e, 0x6c, 0xa4, 0xb4, 0xe7, 0xbb, 0x41, 0x14, 0x93, 0xd0, 0x34, 0xe8, 0x7b, 0x28, 0xbf,
0x1b, 0xdc, 0x49, 0x31, 0xae, 0x33, 0x6b, 0xe8, 0x46, 0xa6, 0x71, 0xbd, 0xe8, 0x64, 0x8f, 0xb4, 0xed, 0x45, 0xf8, 0xe0, 0x9a, 0xe7, 0x3a, 0x4f, 0x34, 0xaf, 0xcb, 0x8f, 0xb6, 0x86, 0x04, 0xd7,
0x1d, 0x5c, 0x25, 0xa6, 0x8a, 0x95, 0x6a, 0xf7, 0x7a, 0xd0, 0x4c, 0xc4, 0x4a, 0x2a, 0x50, 0xd8, 0x05, 0xe6, 0x5c, 0xb2, 0xe3, 0x83, 0x6b, 0xb0, 0x30, 0x84, 0xc6, 0x95, 0xe2, 0xdb, 0x82, 0x34,
0x3f, 0x3a, 0xc2, 0x6d, 0xa9, 0x0e, 0x95, 0x93, 0xd3, 0x83, 0xe3, 0x57, 0xc7, 0x2f, 0x71, 0x45, 0xbc, 0x0d, 0x5b, 0xdd, 0x41, 0x70, 0xf5, 0x16, 0x97, 0x5d, 0x4c, 0xb8, 0x67, 0xf5, 0xbd, 0x28,
0xc2, 0x8f, 0xfe, 0xd1, 0xc9, 0x40, 0x7c, 0xe4, 0x7b, 0x7f, 0x96, 0xa1, 0x36, 0x9f, 0x35, 0xf2, 0x66, 0xfa, 0x12, 0x9a, 0xd9, 0x23, 0x1d, 0x20, 0x8d, 0x3d, 0x7b, 0xaa, 0xea, 0x75, 0x8d, 0xc7,
0x0d, 0x34, 0x13, 0xe1, 0x92, 0xeb, 0x1a, 0x83, 0x65, 0x29, 0x77, 0x6f, 0x2c, 0x3f, 0xd4, 0x91, 0x2c, 0xcc, 0x07, 0x6d, 0xa8, 0x25, 0xc0, 0x21, 0x45, 0xc8, 0xed, 0x9f, 0x9c, 0xe0, 0x7a, 0x56,
0x3d, 0x85, 0x6a, 0xb4, 0x8a, 0x92, 0xcd, 0xe5, 0x5b, 0x6f, 0x77, 0x2b, 0x23, 0xd7, 0x97, 0x9f, 0x81, 0xe2, 0xd9, 0xf9, 0xe1, 0xe9, 0xf1, 0xe9, 0x6b, 0xdc, 0xc9, 0xf0, 0xa3, 0x73, 0x72, 0xd6,
0x41, 0x6d, 0xbe, 0x73, 0x92, 0xb8, 0x56, 0x7c, 0x6f, 0xed, 0x76, 0xb2, 0x07, 0xfa, 0xfe, 0x3e, 0x15, 0x1f, 0x4b, 0xed, 0x3f, 0x96, 0xa1, 0x3c, 0x1b, 0x6e, 0xf2, 0x35, 0xd4, 0x12, 0xf8, 0x90,
0xc0, 0x62, 0xeb, 0x23, 0x9d, 0xab, 0x56, 0xcf, 0xee, 0xf6, 0x92, 0x13, 0x6d, 0xe2, 0x05, 0xd4, 0x9b, 0xda, 0xc9, 0x22, 0x8c, 0x5b, 0xb7, 0x16, 0x1f, 0xea, 0x88, 0x5f, 0x40, 0x29, 0xda, 0x7d,
0x63, 0x4b, 0x1d, 0x89, 0x4d, 0x6f, 0x6a, 0x4b, 0xec, 0x76, 0x97, 0x1d, 0x2d, 0x12, 0x99, 0x6f, 0xc9, 0xe6, 0xe2, 0x35, 0xbb, 0xb5, 0x95, 0x91, 0xeb, 0xcb, 0x2f, 0xa1, 0x3c, 0x5b, 0x72, 0x49,
0x00, 0x64, 0x41, 0x6e, 0xc9, 0x3d, 0x61, 0x9e, 0x48, 0x76, 0x59, 0x78, 0x0c, 0x15, 0xfd, 0xfa, 0x5c, 0x2b, 0xbe, 0x28, 0xb7, 0x9a, 0xd9, 0x03, 0x7d, 0x7f, 0x1f, 0x60, 0xbe, 0x66, 0x92, 0xe6,
0x93, 0x0d, 0xad, 0x94, 0x5c, 0x10, 0xba, 0x9b, 0x69, 0xb1, 0xbe, 0xd9, 0x87, 0x7a, 0x8c, 0x8c, 0x75, 0xbb, 0x6e, 0x6b, 0x7b, 0xc1, 0x89, 0x36, 0x71, 0x00, 0x95, 0xd8, 0x16, 0x49, 0x62, 0x74,
0xe7, 0xf1, 0x67, 0x09, 0x7a, 0x5e, 0x85, 0x34, 0xeb, 0x3d, 0xcc, 0x21, 0x07, 0x34, 0xe2, 0xcf, 0x91, 0x5a, 0x4b, 0x5b, 0xad, 0x45, 0x47, 0xf3, 0x44, 0x66, 0x2b, 0x07, 0x99, 0xb3, 0x69, 0x72,
0x22, 0x99, 0xa7, 0x9a, 0x7d, 0x2b, 0xe7, 0x49, 0x64, 0x1e, 0x35, 0xb4, 0x73, 0x0c, 0xab, 0x49, 0x31, 0x99, 0x25, 0x92, 0xdd, 0x4e, 0x9e, 0x41, 0x51, 0xaf, 0x1b, 0x64, 0x43, 0x2b, 0x25, 0x37,
0x0a, 0x40, 0x42, 0xbf, 0x82, 0x44, 0x94, 0xb1, 0x9b, 0x9f, 0xa4, 0x18, 0xf2, 0x44, 0xfd, 0x8b, 0x92, 0xd6, 0x66, 0x5a, 0xac, 0x6f, 0x76, 0xa0, 0x12, 0x63, 0xff, 0x59, 0xfc, 0xd9, 0x17, 0x61,
0x3c, 0x55, 0xff, 0x0f, 0x09, 0x89, 0x35, 0x42, 0x64, 0x61, 0x2d, 0x21, 0x53, 0xf7, 0x76, 0x72, 0x56, 0x85, 0x34, 0xcd, 0x3e, 0x36, 0x90, 0x74, 0xaa, 0xf1, 0x77, 0x98, 0xcc, 0x52, 0xcd, 0x3e,
0x18, 0xcb, 0x00, 0xff, 0x01, 0xa5, 0xc6, 0x89, 0xfc, 0x2f, 0x52, 0x5e, 0x3e, 0x82, 0xdd, 0xff, 0xce, 0xb3, 0x24, 0x32, 0xaf, 0x28, 0xda, 0x39, 0x85, 0xd5, 0x24, 0xe7, 0xe0, 0x0b, 0x72, 0x0d,
0x5f, 0x79, 0xae, 0x0c, 0x0f, 0xcb, 0xf2, 0x4f, 0xee, 0xa3, 0x7f, 0x02, 0x00, 0x00, 0xff, 0xff, 0x6b, 0x29, 0x63, 0xb7, 0x3f, 0xcb, 0x69, 0xe4, 0xb9, 0xfa, 0xdb, 0x7a, 0xae, 0xfe, 0x90, 0x12,
0xfb, 0x5b, 0x5f, 0x9d, 0xf1, 0x0e, 0x00, 0x00, 0x12, 0x6b, 0x84, 0xc8, 0xc2, 0x5a, 0x42, 0xa6, 0xee, 0xed, 0x18, 0x18, 0x4b, 0x17, 0xff, 0x72,
0xa5, 0xc6, 0x8c, 0xfc, 0x27, 0x52, 0x5e, 0x3c, 0x9a, 0xad, 0xff, 0x5e, 0x7b, 0xae, 0x0c, 0xf7,
0x97, 0xe5, 0xbf, 0xea, 0xa7, 0x7f, 0x07, 0x00, 0x00, 0xff, 0xff, 0x86, 0xfc, 0xda, 0xe9, 0x62,
0x0f, 0x00, 0x00,
} }

@ -222,9 +222,17 @@ message WalletBalanceResponse {
double balance = 1; double balance = 1;
} }
message RTChannel {
string id1 = 1;
string id2 = 2;
string edgeID = 3;
double capacity = 4;
double weight = 5;
}
message ShowRoutingTableRequest { message ShowRoutingTableRequest {
} }
message ShowRoutingTableResponse { message ShowRoutingTableResponse {
string rt = 1; repeated RTChannel channels = 1;
} }

@ -5,7 +5,6 @@
package lnwire package lnwire
import ( import (
"encoding/gob"
"fmt" "fmt"
"io" "io"
@ -18,16 +17,13 @@ type NeighborHelloMessage struct {
} }
func (msg *NeighborHelloMessage) Decode(r io.Reader, pver uint32) error { func (msg *NeighborHelloMessage) Decode(r io.Reader, pver uint32) error {
decoder := gob.NewDecoder(r) rt1, err := rt.UnmarshallRoutingTable(r)
rt1 := rt.NewRoutingTable()
err := decoder.Decode(rt1.G)
msg.RT = rt1 msg.RT = rt1
return err return err
} }
func (msg *NeighborHelloMessage) Encode(w io.Writer, pver uint32) error { func (msg *NeighborHelloMessage) Encode(w io.Writer, pver uint32) error {
encoder := gob.NewEncoder(w) err := msg.RT.Marshall(w)
err := encoder.Encode(msg.RT.G)
return err return err
} }

@ -512,7 +512,19 @@ func (r *rpcServer) ShowRoutingTable(ctx context.Context,
in *lnrpc.ShowRoutingTableRequest) (*lnrpc.ShowRoutingTableResponse, error) { in *lnrpc.ShowRoutingTableRequest) (*lnrpc.ShowRoutingTableResponse, error) {
rpcsLog.Debugf("[ShowRoutingTable]") rpcsLog.Debugf("[ShowRoutingTable]")
rtCopy := r.server.routingMgr.GetRTCopy() rtCopy := r.server.routingMgr.GetRTCopy()
channels := make([]*lnrpc.RTChannel, 0)
for _, channel := range rtCopy.AllChannels() {
channels = append(channels,
&lnrpc.RTChannel{
Id1: channel.Id1.String(),
Id2: channel.Id2.String(),
EdgeID: channel.EdgeID.String(),
Capacity: channel.Info.Capacity(),
Weight: channel.Info.Weight(),
},
)
}
return &lnrpc.ShowRoutingTableResponse{ return &lnrpc.ShowRoutingTableResponse{
Rt: rtCopy.String(), Channels: channels,
}, nil }, nil
} }