Skip to content

Commit

Permalink
collectors: collect inbound fee stats
Browse files Browse the repository at this point in the history
We collect non-zero inbound base fees and fee rates in terms of
histograms to track the adoption and values set. The histograms are
separated into positive and negative portions.
  • Loading branch information
bitromortac committed Oct 30, 2024
1 parent 363cab6 commit c766291
Showing 1 changed file with 90 additions and 0 deletions.
90 changes: 90 additions & 0 deletions collectors/graph_collector.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,32 @@ package collectors
import (
"context"
"fmt"
"math"

"github.com/lightninglabs/lndclient"
"github.com/prometheus/client_golang/prometheus"
)

const (
// inboundFeeFeatureBits is the feature id used to advertise inbound
// fees in gossip TLV extensions.
inboundFeeFeatureBits = 55555

// Define some collector names and help texts for inbound fees.
inboundFeeRateName = "lnd_graph_inbound_fee_rate_msat_histogram"
inboundFeeBaseName = "lnd_graph_inbound_fee_base_msat_histogram"
inboundFeeRateHelp = "histogram of inbound fee rates for channel " +
"routing policies in msat"
inboundFeeBaseHelp = "histogram of inbound base fees for channel " +
"routing policies in msat"

// Define labels to categorize inbound fees into negative and positive
// buckets.
inboundFeeSignLabel = "sign"
inboundFeeSignLabelPositive = "positive"
inboundFeeSignLabelNegative = "negative"
)

// GraphCollector is a collector that keeps track of graph information.
type GraphCollector struct {
numEdgesDesc *prometheus.Desc
Expand Down Expand Up @@ -46,6 +67,9 @@ type GraphCollector struct {
minFeeRateMsatDesc *prometheus.Desc
avgFeeRateMsatDesc *prometheus.Desc

inboundFeeBaseMsatDesc *prometheus.Desc
inboundFeeRateMsatDesc *prometheus.Desc

medianMaxHtlcMsatDesc *prometheus.Desc
maxMaxHtlcMsatDesc *prometheus.Desc
minMaxHtlcMsatDesc *prometheus.Desc
Expand Down Expand Up @@ -207,6 +231,15 @@ func NewGraphCollector(lnd lndclient.LightningClient,
nil, nil,
),

inboundFeeBaseMsatDesc: prometheus.NewDesc(
inboundFeeBaseName, inboundFeeBaseHelp,
[]string{inboundFeeSignLabel}, nil,
),
inboundFeeRateMsatDesc: prometheus.NewDesc(
inboundFeeRateName, inboundFeeRateHelp,
[]string{inboundFeeSignLabel}, nil,
),

medianMaxHtlcMsatDesc: prometheus.NewDesc(
"lnd_graph_max_htlc_msat_median",
"median max htlc for a channel routing policy in msat",
Expand Down Expand Up @@ -274,6 +307,9 @@ func (g *GraphCollector) Describe(ch chan<- *prometheus.Desc) {
ch <- g.avgFeeRateMsatDesc
ch <- g.medianFeeRateMsatDesc

ch <- g.inboundFeeBaseMsatDesc
ch <- g.inboundFeeRateMsatDesc

ch <- g.minMaxHtlcMsatDesc
ch <- g.maxMaxHtlcMsatDesc
ch <- g.avgMaxHtlcMsatDesc
Expand Down Expand Up @@ -366,6 +402,27 @@ func (g *GraphCollector) collectRoutingPolicyMetrics(

feeBaseStats = newStatsCompiler(numEdges)
feeRateStats = newStatsCompiler(numEdges)

inboundFeeBaseStats = prometheus.NewHistogramVec(
prometheus.HistogramOpts{
Name: inboundFeeBaseName,
Help: inboundFeeBaseHelp,
Buckets: prometheus.ExponentialBuckets(
1, 2, 20, // 1 to 1_048_576 msat
),
},
[]string{inboundFeeSignLabel},
)
inboundFeeRateStats = prometheus.NewHistogramVec(
prometheus.HistogramOpts{
Name: inboundFeeRateName,
Help: inboundFeeRateHelp,
Buckets: prometheus.ExponentialBuckets(
1, 2, 15, // 1 to 32768 PPM ~ 3 %
),
},
[]string{inboundFeeSignLabel},
)
)

for _, edge := range edges {
Expand All @@ -385,6 +442,36 @@ func (g *GraphCollector) collectRoutingPolicyMetrics(

feeBaseStats.Observe(float64(policy.FeeBaseMsat))
feeRateStats.Observe(float64(policy.FeeRateMilliMsat))

// Collect optional non-zero inbound fee statistics.
_, ok := policy.CustomRecords[inboundFeeFeatureBits]
if ok {
absBase := math.Abs(float64(
policy.InboundBaseFeeMsat,
))
if policy.InboundBaseFeeMsat < 0 {
inboundFeeBaseStats.WithLabelValues(
inboundFeeSignLabelNegative,
).Observe(absBase)
} else if policy.InboundBaseFeeMsat > 0 {
inboundFeeBaseStats.WithLabelValues(
inboundFeeSignLabelPositive,
).Observe(absBase)
}

absRate := math.Abs(
float64(policy.InboundFeeRatePPM),
)
if policy.InboundFeeRatePPM < 0 {
inboundFeeRateStats.WithLabelValues(
inboundFeeSignLabelNegative,
).Observe(absRate)
} else if policy.InboundFeeRatePPM > 0 {
inboundFeeRateStats.WithLabelValues(
inboundFeeSignLabelPositive,
).Observe(absRate)
}
}
}
}

Expand Down Expand Up @@ -478,4 +565,7 @@ func (g *GraphCollector) collectRoutingPolicyMetrics(
g.medianFeeRateMsatDesc, prometheus.GaugeValue,
feeRateReport.median,
)

inboundFeeBaseStats.Collect(ch)
inboundFeeRateStats.Collect(ch)
}

0 comments on commit c766291

Please sign in to comment.