Merge pull request #2312 from xsb/color-node-update

rpc: add node color to NodeUpdate and GetInfo
This commit is contained in:
Johan T. Halseth 2019-05-23 14:21:05 +02:00 committed by GitHub
commit 6cd71b7f7a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 560 additions and 489 deletions

View File

@ -1840,6 +1840,7 @@ func getInfo(ctx *cli.Context) error {
Version string `json:"version"` Version string `json:"version"`
IdentityPubkey string `json:"identity_pubkey"` IdentityPubkey string `json:"identity_pubkey"`
Alias string `json:"alias"` Alias string `json:"alias"`
Color string `json:"color"`
NumPendingChannels uint32 `json:"num_pending_channels"` NumPendingChannels uint32 `json:"num_pending_channels"`
NumActiveChannels uint32 `json:"num_active_channels"` NumActiveChannels uint32 `json:"num_active_channels"`
NumInactiveChannels uint32 `json:"num_inactive_channels"` NumInactiveChannels uint32 `json:"num_inactive_channels"`
@ -1855,6 +1856,7 @@ func getInfo(ctx *cli.Context) error {
Version: resp.Version, Version: resp.Version,
IdentityPubkey: resp.IdentityPubkey, IdentityPubkey: resp.IdentityPubkey,
Alias: resp.Alias, Alias: resp.Alias,
Color: resp.Color,
NumPendingChannels: resp.NumPendingChannels, NumPendingChannels: resp.NumPendingChannels,
NumActiveChannels: resp.NumActiveChannels, NumActiveChannels: resp.NumActiveChannels,
NumInactiveChannels: resp.NumInactiveChannels, NumInactiveChannels: resp.NumInactiveChannels,

File diff suppressed because it is too large Load Diff

View File

@ -1329,6 +1329,9 @@ message GetInfoResponse {
/// A list of active chains the node is connected to /// A list of active chains the node is connected to
repeated Chain chains = 16 [json_name = "chains"]; repeated Chain chains = 16 [json_name = "chains"];
/// The color of the current node in hex code format
string color = 17 [json_name = "color"];
} }
message Chain { message Chain {
@ -1854,6 +1857,7 @@ message NodeUpdate {
string identity_key = 2; string identity_key = 2;
bytes global_features = 3; bytes global_features = 3;
string alias = 4; string alias = 4;
string color = 5;
} }
message ChannelEdgeUpdate { message ChannelEdgeUpdate {
/** /**

View File

@ -2158,6 +2158,10 @@
"$ref": "#/definitions/lnrpcChain" "$ref": "#/definitions/lnrpcChain"
}, },
"title": "/ A list of active chains the node is connected to" "title": "/ A list of active chains the node is connected to"
},
"color": {
"type": "string",
"title": "/ The color of the current node in hex code format"
} }
} }
}, },
@ -2639,6 +2643,9 @@
}, },
"alias": { "alias": {
"type": "string" "type": "string"
},
"color": {
"type": "string"
} }
} }
}, },

View File

@ -2,6 +2,7 @@ package routing
import ( import (
"fmt" "fmt"
"image/color"
"net" "net"
"sync" "sync"
"sync/atomic" "sync/atomic"
@ -246,6 +247,9 @@ type NetworkNodeUpdate struct {
// Alias is the alias or nick name of the node. // Alias is the alias or nick name of the node.
Alias string Alias string
// Color is the node's color in hex code format.
Color string
} }
// ChannelEdgeUpdate is an update for a new channel within the ChannelGraph. // ChannelEdgeUpdate is an update for a new channel within the ChannelGraph.
@ -321,6 +325,7 @@ func addToTopologyChange(graph *channeldb.ChannelGraph, update *TopologyChange,
Addresses: m.Addresses, Addresses: m.Addresses,
IdentityKey: pubKey, IdentityKey: pubKey,
Alias: m.Alias, Alias: m.Alias,
Color: EncodeHexColor(m.Color),
} }
nodeUpdate.IdentityKey.Curve = nil nodeUpdate.IdentityKey.Curve = nil
@ -388,3 +393,8 @@ func addToTopologyChange(graph *channeldb.ChannelGraph, update *TopologyChange,
"unknown message type %T", msg) "unknown message type %T", msg)
} }
} }
// EncodeHexColor takes a color and returns it in hex code format.
func EncodeHexColor(color color.RGBA) string {
return fmt.Sprintf("#%02x%02x%02x", color.R, color.G, color.B)
}

View File

@ -628,6 +628,10 @@ func TestNodeUpdateNotification(t *testing.T) {
t.Fatalf("node alias doesn't match: expected %v, got %v", t.Fatalf("node alias doesn't match: expected %v, got %v",
ann.Alias, nodeUpdate.Alias) ann.Alias, nodeUpdate.Alias)
} }
if nodeUpdate.Color != EncodeHexColor(ann.Color) {
t.Fatalf("node color doesn't match: expected %v, got %v",
EncodeHexColor(ann.Color), nodeUpdate.Color)
}
} }
// Create lookup map for notifications we are intending to receive. Entries // Create lookup map for notifications we are intending to receive. Entries
@ -926,3 +930,30 @@ func TestChannelCloseNotification(t *testing.T) {
t.Fatal("notification not sent") t.Fatal("notification not sent")
} }
} }
// TestEncodeHexColor tests that the string used to represent a node color is
// correctly encoded.
func TestEncodeHexColor(t *testing.T) {
var colorTestCases = []struct {
R uint8
G uint8
B uint8
encoded string
isValid bool
}{
{0, 0, 0, "#000000", true},
{255, 255, 255, "#ffffff", true},
{255, 117, 215, "#ff75d7", true},
{0, 0, 0, "000000", false},
{1, 2, 3, "", false},
{1, 2, 3, "#", false},
}
for _, tc := range colorTestCases {
encoded := EncodeHexColor(color.RGBA{tc.R, tc.G, tc.B, 0})
if (encoded == tc.encoded) != tc.isValid {
t.Fatalf("incorrect color encoding, "+
"want: %v, got: %v", tc.encoded, encoded)
}
}
}

View File

@ -2002,6 +2002,7 @@ func (r *rpcServer) GetInfo(ctx context.Context,
Chains: activeChains, Chains: activeChains,
Uris: uris, Uris: uris,
Alias: nodeAnn.Alias.String(), Alias: nodeAnn.Alias.String(),
Color: routing.EncodeHexColor(nodeAnn.RGBColor),
BestHeaderTimestamp: int64(bestHeaderTimestamp), BestHeaderTimestamp: int64(bestHeaderTimestamp),
Version: build.Version(), Version: build.Version(),
}, nil }, nil
@ -3677,13 +3678,12 @@ func (r *rpcServer) DescribeGraph(ctx context.Context,
nodeAddrs = append(nodeAddrs, nodeAddr) nodeAddrs = append(nodeAddrs, nodeAddr)
} }
nodeColor := fmt.Sprintf("#%02x%02x%02x", node.Color.R, node.Color.G, node.Color.B)
resp.Nodes = append(resp.Nodes, &lnrpc.LightningNode{ resp.Nodes = append(resp.Nodes, &lnrpc.LightningNode{
LastUpdate: uint32(node.LastUpdate.Unix()), LastUpdate: uint32(node.LastUpdate.Unix()),
PubKey: hex.EncodeToString(node.PubKeyBytes[:]), PubKey: hex.EncodeToString(node.PubKeyBytes[:]),
Addresses: nodeAddrs, Addresses: nodeAddrs,
Alias: node.Alias, Alias: node.Alias,
Color: nodeColor, Color: routing.EncodeHexColor(node.Color),
}) })
return nil return nil
@ -3841,14 +3841,13 @@ func (r *rpcServer) GetNodeInfo(ctx context.Context,
} }
// TODO(roasbeef): list channels as well? // TODO(roasbeef): list channels as well?
nodeColor := fmt.Sprintf("#%02x%02x%02x", node.Color.R, node.Color.G, node.Color.B)
return &lnrpc.NodeInfo{ return &lnrpc.NodeInfo{
Node: &lnrpc.LightningNode{ Node: &lnrpc.LightningNode{
LastUpdate: uint32(node.LastUpdate.Unix()), LastUpdate: uint32(node.LastUpdate.Unix()),
PubKey: in.PubKey, PubKey: in.PubKey,
Addresses: nodeAddrs, Addresses: nodeAddrs,
Alias: node.Alias, Alias: node.Alias,
Color: nodeColor, Color: routing.EncodeHexColor(node.Color),
}, },
NumChannels: numChannels, NumChannels: numChannels,
TotalCapacity: int64(totalCapacity), TotalCapacity: int64(totalCapacity),
@ -4078,6 +4077,7 @@ func marshallTopologyChange(topChange *routing.TopologyChange) *lnrpc.GraphTopol
IdentityKey: encodeKey(nodeUpdate.IdentityKey), IdentityKey: encodeKey(nodeUpdate.IdentityKey),
GlobalFeatures: nodeUpdate.GlobalFeatures, GlobalFeatures: nodeUpdate.GlobalFeatures,
Alias: nodeUpdate.Alias, Alias: nodeUpdate.Alias,
Color: nodeUpdate.Color,
} }
} }