mirror of
https://github.com/lightningnetwork/lnd.git
synced 2024-11-19 18:10:34 +01:00
Merge pull request #1742 from halseth/remove-render-option
Remove --render option from `lncli describegraph`
This commit is contained in:
commit
9c4d069dbc
14
Gopkg.lock
generated
14
Gopkg.lock
generated
@ -63,19 +63,6 @@
|
||||
pruneopts = "UT"
|
||||
revision = "e404fcfc888570cadd1610538e2dbc89f66af814"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:9c78699f117ea9ee1923694ee8c13e1a94bd8cf311b2797c96521359a5d8ae10"
|
||||
name = "github.com/awalterschulze/gographviz"
|
||||
packages = [
|
||||
".",
|
||||
"ast",
|
||||
"parser",
|
||||
"scanner",
|
||||
"token",
|
||||
]
|
||||
pruneopts = "UT"
|
||||
revision = "761fd5fbb34e4c2c138c280395b65b48e4ff5a53"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:f944518b25f8733eed1d13855eeaaeda9b1f56c2bc75223a7e3427c024168eba"
|
||||
name = "github.com/btcsuite/btcd"
|
||||
@ -493,7 +480,6 @@
|
||||
input-imports = [
|
||||
"github.com/NebulousLabs/go-upnp",
|
||||
"github.com/Yawning/aez",
|
||||
"github.com/awalterschulze/gographviz",
|
||||
"github.com/btcsuite/btcd/blockchain",
|
||||
"github.com/btcsuite/btcd/btcec",
|
||||
"github.com/btcsuite/btcd/btcjson",
|
||||
|
@ -1,7 +1,3 @@
|
||||
[[constraint]]
|
||||
name = "github.com/awalterschulze/gographviz"
|
||||
revision = "761fd5fbb34e4c2c138c280395b65b48e4ff5a53"
|
||||
|
||||
[[constraint]]
|
||||
name = "github.com/btcsuite/btclog"
|
||||
revision = "84c8d2346e9fc8c7b947e243b9c24e6df9fd206a"
|
||||
|
@ -11,15 +11,12 @@ import (
|
||||
"io/ioutil"
|
||||
"math"
|
||||
"os"
|
||||
"os/exec"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
"syscall"
|
||||
|
||||
"github.com/awalterschulze/gographviz"
|
||||
"github.com/btcsuite/btcd/chaincfg/chainhash"
|
||||
"github.com/btcsuite/btcutil"
|
||||
"github.com/golang/protobuf/jsonpb"
|
||||
"github.com/golang/protobuf/proto"
|
||||
"github.com/lightningnetwork/lnd/lnrpc"
|
||||
@ -2343,13 +2340,7 @@ var describeGraphCommand = cli.Command{
|
||||
Category: "Peers",
|
||||
Description: "Prints a human readable version of the known channel " +
|
||||
"graph from the PoV of the node",
|
||||
Usage: "Describe the network graph.",
|
||||
Flags: []cli.Flag{
|
||||
cli.BoolFlag{
|
||||
Name: "render",
|
||||
Usage: "If set, then an image of graph will be generated and displayed. The generated image is stored within the current directory with a file name of 'graph.svg'",
|
||||
},
|
||||
},
|
||||
Usage: "Describe the network graph.",
|
||||
Action: actionDecorator(describeGraph),
|
||||
}
|
||||
|
||||
@ -2364,12 +2355,6 @@ func describeGraph(ctx *cli.Context) error {
|
||||
return err
|
||||
}
|
||||
|
||||
// If the draw flag is on, then we'll use the 'dot' command to create a
|
||||
// visualization of the graph itself.
|
||||
if ctx.Bool("render") {
|
||||
return drawChannelGraph(graph)
|
||||
}
|
||||
|
||||
printRespJSON(graph)
|
||||
return nil
|
||||
}
|
||||
@ -2405,135 +2390,6 @@ func normalizeFunc(edges []*lnrpc.ChannelEdge, scaleFactor float64) func(int64)
|
||||
}
|
||||
}
|
||||
|
||||
func drawChannelGraph(graph *lnrpc.ChannelGraph) error {
|
||||
// First we'll create a temporary file that we'll write the compiled
|
||||
// string that describes our graph in the dot format to.
|
||||
tempDotFile, err := ioutil.TempFile("", "")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer os.Remove(tempDotFile.Name())
|
||||
|
||||
// Next, we'll create (or re-create) the file that the final graph
|
||||
// image will be written to.
|
||||
imageFile, err := os.Create("graph.svg")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// With our temporary files set up, we'll initialize the graphviz
|
||||
// object that we'll use to draw our graph.
|
||||
graphName := "LightningNetwork"
|
||||
graphCanvas := gographviz.NewGraph()
|
||||
graphCanvas.SetName(graphName)
|
||||
graphCanvas.SetDir(false)
|
||||
|
||||
const numKeyChars = 10
|
||||
|
||||
truncateStr := func(k string, n uint) string {
|
||||
return k[:n]
|
||||
}
|
||||
|
||||
// For each node within the graph, we'll add a new vertex to the graph.
|
||||
for _, node := range graph.Nodes {
|
||||
// Rather than using the entire hex-encoded string, we'll only
|
||||
// use the first 10 characters. We also add a prefix of "Z" as
|
||||
// graphviz is unable to parse the compressed pubkey as a
|
||||
// non-integer.
|
||||
//
|
||||
// TODO(roasbeef): should be able to get around this?
|
||||
nodeID := fmt.Sprintf(`"%v"`, truncateStr(node.PubKey, numKeyChars))
|
||||
|
||||
attrs := gographviz.Attrs{}
|
||||
|
||||
if node.Color != "" {
|
||||
attrs["color"] = fmt.Sprintf(`"%v"`, node.Color)
|
||||
}
|
||||
|
||||
graphCanvas.AddNode(graphName, nodeID, attrs)
|
||||
}
|
||||
|
||||
normalize := normalizeFunc(graph.Edges, 3)
|
||||
|
||||
// Similarly, for each edge we'll add an edge between the corresponding
|
||||
// nodes added to the graph above.
|
||||
for _, edge := range graph.Edges {
|
||||
// Once again, we add a 'Z' prefix so we're compliant with the
|
||||
// dot grammar.
|
||||
src := fmt.Sprintf(`"%v"`, truncateStr(edge.Node1Pub, numKeyChars))
|
||||
dest := fmt.Sprintf(`"%v"`, truncateStr(edge.Node2Pub, numKeyChars))
|
||||
|
||||
// The weight for our edge will be the total capacity of the
|
||||
// channel, in BTC.
|
||||
// TODO(roasbeef): can also factor in the edges time-lock delta
|
||||
// and fee information
|
||||
amt := btcutil.Amount(edge.Capacity).ToBTC()
|
||||
edgeWeight := strconv.FormatFloat(amt, 'f', -1, 64)
|
||||
|
||||
// The label for each edge will simply be a truncated version
|
||||
// of its channel ID.
|
||||
chanIDStr := strconv.FormatUint(edge.ChannelId, 10)
|
||||
edgeLabel := fmt.Sprintf(`"cid:%v"`, truncateStr(chanIDStr, 7))
|
||||
|
||||
// We'll also use a normalized version of the channels'
|
||||
// capacity in satoshis in order to modulate the "thickness" of
|
||||
// the line that creates the edge within the graph.
|
||||
normalizedCapacity := normalize(edge.Capacity)
|
||||
edgeThickness := strconv.FormatFloat(normalizedCapacity, 'f', -1, 64)
|
||||
|
||||
// If there's only a single channel in the graph, then we'll
|
||||
// just set the edge thickness to 1 for everything.
|
||||
if math.IsNaN(normalizedCapacity) {
|
||||
edgeThickness = "1"
|
||||
}
|
||||
|
||||
// TODO(roasbeef): color code based on percentile capacity
|
||||
graphCanvas.AddEdge(src, dest, false, gographviz.Attrs{
|
||||
"penwidth": edgeThickness,
|
||||
"weight": edgeWeight,
|
||||
"label": edgeLabel,
|
||||
})
|
||||
}
|
||||
|
||||
// With the declarative generation of the graph complete, we now write
|
||||
// the dot-string description of the graph
|
||||
graphDotString := graphCanvas.String()
|
||||
if _, err := tempDotFile.WriteString(graphDotString); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := tempDotFile.Sync(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var errBuffer bytes.Buffer
|
||||
|
||||
// Once our dot file has been written to disk, we can use the dot
|
||||
// command itself to generate the drawn rendering of the graph
|
||||
// described.
|
||||
drawCmd := exec.Command("dot", "-T"+"svg", "-o"+imageFile.Name(),
|
||||
tempDotFile.Name())
|
||||
drawCmd.Stderr = &errBuffer
|
||||
if err := drawCmd.Run(); err != nil {
|
||||
fmt.Println("error rendering graph: ", errBuffer.String())
|
||||
fmt.Println("dot: ", graphDotString)
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
errBuffer.Reset()
|
||||
|
||||
// Finally, we'll open the drawn graph to display to the user.
|
||||
openCmd := exec.Command("open", imageFile.Name())
|
||||
openCmd.Stderr = &errBuffer
|
||||
if err := openCmd.Run(); err != nil {
|
||||
fmt.Println("error opening rendered graph image: ",
|
||||
errBuffer.String())
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
var listPaymentsCommand = cli.Command{
|
||||
Name: "listpayments",
|
||||
Category: "Payments",
|
||||
|
Loading…
Reference in New Issue
Block a user