lncli: remove --render option from describegraph
This commit is contained in:
parent
643618b4f6
commit
c39c2d7c37
@ -11,15 +11,12 @@ import (
|
|||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"math"
|
"math"
|
||||||
"os"
|
"os"
|
||||||
"os/exec"
|
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
"syscall"
|
"syscall"
|
||||||
|
|
||||||
"github.com/awalterschulze/gographviz"
|
|
||||||
"github.com/btcsuite/btcd/chaincfg/chainhash"
|
"github.com/btcsuite/btcd/chaincfg/chainhash"
|
||||||
"github.com/btcsuite/btcutil"
|
|
||||||
"github.com/golang/protobuf/jsonpb"
|
"github.com/golang/protobuf/jsonpb"
|
||||||
"github.com/golang/protobuf/proto"
|
"github.com/golang/protobuf/proto"
|
||||||
"github.com/lightningnetwork/lnd/lnrpc"
|
"github.com/lightningnetwork/lnd/lnrpc"
|
||||||
@ -2344,12 +2341,6 @@ var describeGraphCommand = cli.Command{
|
|||||||
Description: "Prints a human readable version of the known channel " +
|
Description: "Prints a human readable version of the known channel " +
|
||||||
"graph from the PoV of the node",
|
"graph from the PoV of the node",
|
||||||
Usage: "Describe the network graph.",
|
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'",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
Action: actionDecorator(describeGraph),
|
Action: actionDecorator(describeGraph),
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2364,12 +2355,6 @@ func describeGraph(ctx *cli.Context) error {
|
|||||||
return err
|
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)
|
printRespJSON(graph)
|
||||||
return nil
|
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{
|
var listPaymentsCommand = cli.Command{
|
||||||
Name: "listpayments",
|
Name: "listpayments",
|
||||||
Category: "Payments",
|
Category: "Payments",
|
||||||
|
Loading…
Reference in New Issue
Block a user