mirror of
https://github.com/lightninglabs/faraday.git
synced 2026-08-13 12:33:35 +02:00
Add the frcli forwardingability command to query the RPC over a time range and optional liquidity floor. It decodes the sparse response and prints each pair with its raw effective uptime and forwarded volume, plus uptime fraction and velocity derived from the reported window.
122 lines
3 KiB
Go
122 lines
3 KiB
Go
package main
|
|
|
|
import (
|
|
"context"
|
|
"sort"
|
|
|
|
"github.com/lightninglabs/faraday/frdrpc"
|
|
"github.com/urfave/cli"
|
|
)
|
|
|
|
var forwardingAbilityCommand = cli.Command{
|
|
Name: "forwardingability",
|
|
Category: "insights",
|
|
Usage: "Get forwarding ability analysis of peer pairs.",
|
|
Flags: []cli.Flag{
|
|
cli.Uint64Flag{
|
|
Name: "start_time",
|
|
Usage: "start time of the query range as a unix " +
|
|
"timestamp",
|
|
},
|
|
cli.Uint64Flag{
|
|
Name: "end_time",
|
|
Usage: "end time of the query range as a unix " +
|
|
"timestamp; zero defaults to the server's " +
|
|
"current time",
|
|
},
|
|
cli.Uint64Flag{
|
|
Name: "liquidity_floor_sat",
|
|
Usage: "the minimum directional liquidity in " +
|
|
"satoshis for a pair to count as " +
|
|
"economically forwardable; zero uses the " +
|
|
"server default",
|
|
},
|
|
cli.Float64Flag{
|
|
Name: "uptime_threshold",
|
|
Usage: "the uptime fraction in [0,1] at or above " +
|
|
"which a non-forwarding pair is reported as " +
|
|
"up but idle; zero uses the server default",
|
|
},
|
|
},
|
|
Action: queryForwardingAbility,
|
|
}
|
|
|
|
type pairView struct {
|
|
PeerIn string `json:"peer_in"`
|
|
PeerOut string `json:"peer_out"`
|
|
EffectiveUptimeS int64 `json:"effective_uptime_s"`
|
|
ForwardedSat int64 `json:"forwarded_sat"`
|
|
UptimeFraction float64 `json:"uptime_fraction"`
|
|
Velocity float64 `json:"velocity"`
|
|
}
|
|
|
|
func queryForwardingAbility(ctx *cli.Context) error {
|
|
client, cleanup := getClient(ctx)
|
|
defer cleanup()
|
|
|
|
req := &frdrpc.ForwardingAbilityRequest{
|
|
StartTime: ctx.Uint64("start_time"),
|
|
EndTime: ctx.Uint64("end_time"),
|
|
LiquidityFloorSat: ctx.Uint64("liquidity_floor_sat"),
|
|
UptimeThreshold: ctx.Float64("uptime_threshold"),
|
|
}
|
|
|
|
rpcCtx := context.Background()
|
|
resp, err := client.ForwardingAbility(rpcCtx, req)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
abilities, err := frdrpc.DecodeForwardingAbility(resp)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
// The metrics are raw, so derive uptime fraction and velocity here from
|
|
// the window the server reported.
|
|
windowSeconds := resp.EndTime - resp.StartTime
|
|
|
|
var views []pairView
|
|
for inPeer, outMap := range abilities {
|
|
for outPeer, ability := range outMap {
|
|
var uptimeFraction, velocity float64
|
|
if windowSeconds > 0 {
|
|
uptimeFraction = float64(
|
|
ability.EffectiveUptimeS,
|
|
) / float64(windowSeconds)
|
|
}
|
|
|
|
if ability.EffectiveUptimeS > 0 {
|
|
velocity = float64(ability.ForwardedSat) /
|
|
float64(ability.EffectiveUptimeS)
|
|
}
|
|
|
|
views = append(
|
|
views, pairView{
|
|
PeerIn: inPeer,
|
|
PeerOut: outPeer,
|
|
EffectiveUptimeS: ability.EffectiveUptimeS,
|
|
ForwardedSat: ability.ForwardedSat,
|
|
UptimeFraction: uptimeFraction,
|
|
Velocity: velocity,
|
|
},
|
|
)
|
|
}
|
|
}
|
|
|
|
// Stable sort by PeerIn, then PeerOut.
|
|
sort.SliceStable(
|
|
views,
|
|
func(i, j int) bool {
|
|
if views[i].PeerIn != views[j].PeerIn {
|
|
return views[i].PeerIn < views[j].PeerIn
|
|
}
|
|
|
|
return views[i].PeerOut < views[j].PeerOut
|
|
},
|
|
)
|
|
|
|
printJSON(views)
|
|
|
|
return nil
|
|
}
|