pub struct ProbabilisticScorer<G: Deref<Target = NetworkGraph<L>>, L: Deref>{ /* private fields */ }Expand description
ScoreLookUp implementation using channel success probability distributions.
Channels are tracked with upper and lower liquidity bounds - when an HTLC fails at a channel, we learn that the upper-bound on the available liquidity is lower than the amount of the HTLC. When a payment is forwarded through a channel (but fails later in the route), we learn the lower-bound on the channel’s available liquidity must be at least the value of the HTLC.
These bounds are then used to determine a success probability using the formula from
Optimally Reliable & Cheap Payment Flows on the Lightning Network by Rene Pickhardt
and Stefan Richter [1] (i.e. (upper_bound - payment_amount) / (upper_bound - lower_bound)).
This probability is combined with the liquidity_penalty_multiplier_msat and
liquidity_penalty_amount_multiplier_msat parameters to calculate a concrete penalty in
milli-satoshis. The penalties, when added across all hops, have the property of being linear in
terms of the entire path’s success probability. This allows the router to directly compare
penalties for different paths. See the documentation of those parameters for the exact formulas.
The liquidity bounds are decayed by halving them every liquidity_offset_half_life.
Further, we track the history of our upper and lower liquidity bounds for each channel,
allowing us to assign a second penalty (using historical_liquidity_penalty_multiplier_msat
and historical_liquidity_penalty_amount_multiplier_msat) based on the same probability
formula, but using the history of a channel rather than our latest estimates for the liquidity
bounds.
Implementations§
Source§impl<G: Deref<Target = NetworkGraph<L>>, L: Deref> ProbabilisticScorer<G, L>
impl<G: Deref<Target = NetworkGraph<L>>, L: Deref> ProbabilisticScorer<G, L>
Sourcepub fn new(
decay_params: ProbabilisticScoringDecayParameters,
network_graph: G,
logger: L,
) -> Self
pub fn new( decay_params: ProbabilisticScoringDecayParameters, network_graph: G, logger: L, ) -> Self
Creates a new scorer using the given scoring parameters for sending payments from a node through a network graph.
Sourcepub fn debug_log_liquidity_stats(&self)
pub fn debug_log_liquidity_stats(&self)
Dump the contents of this scorer into the configured logger.
Note that this writes roughly one line per channel for which we have a liquidity estimate, which may be a substantial amount of log output.
Sourcepub fn estimated_channel_liquidity_range(
&self,
scid: u64,
target: &NodeId,
) -> Option<(u64, u64)>
pub fn estimated_channel_liquidity_range( &self, scid: u64, target: &NodeId, ) -> Option<(u64, u64)>
Query the estimated minimum and maximum liquidity available for sending a payment over the
channel with scid towards the given target node.
Sourcepub fn historical_estimated_channel_liquidity_probabilities(
&self,
scid: u64,
target: &NodeId,
) -> Option<([u16; 32], [u16; 32])>
pub fn historical_estimated_channel_liquidity_probabilities( &self, scid: u64, target: &NodeId, ) -> Option<([u16; 32], [u16; 32])>
Query the historical estimated minimum and maximum liquidity available for sending a
payment over the channel with scid towards the given target node.
Returns two sets of 32 buckets. The first set describes the lower-bound liquidity history, the second set describes the upper-bound liquidity history. Each bucket describes the relative frequency at which we’ve seen a liquidity bound in the bucket’s range relative to the channel’s total capacity, on an arbitrary scale. Because the values are slowly decayed, more recent data points are weighted more heavily than older datapoints.
Note that the range of each bucket varies by its location to provide more granular results at the edges of a channel’s capacity, where it is more likely to sit.
When scoring, the estimated probability that an upper-/lower-bound lies in a given bucket is calculated by dividing that bucket’s value with the total value of all buckets.
For example, using a lower bucket count for illustrative purposes, a value of
[0, 0, 0, ..., 0, 32] indicates that we believe the probability of a bound being very
close to the channel’s capacity to be 100%, and have never (recently) seen it in any other
bucket. A value of [31, 0, 0, ..., 0, 0, 32] indicates we’ve seen the bound being both
in the top and bottom bucket, and roughly with similar (recent) frequency.
Because the datapoints are decayed slowly over time, values will eventually return to
Some(([0; 32], [0; 32])) or None if no data remains for a channel.
In order to fetch a single success probability from the buckets provided here, as used in
the scoring model, see Self::historical_estimated_payment_success_probability.
Sourcepub fn historical_estimated_payment_success_probability(
&self,
scid: u64,
target: &NodeId,
amount_msat: u64,
params: &ProbabilisticScoringFeeParameters,
allow_fallback_estimation: bool,
) -> Option<f64>
pub fn historical_estimated_payment_success_probability( &self, scid: u64, target: &NodeId, amount_msat: u64, params: &ProbabilisticScoringFeeParameters, allow_fallback_estimation: bool, ) -> Option<f64>
Query the probability of payment success sending the given amount_msat over the channel
with scid towards the given target node, based on the historical estimated liquidity
bounds.
Returns None if:
- the given channel is not in the network graph, the provided
targetis not a party to the channel, or we don’t have forwarding parameters for either direction in the channel. allow_fallback_estimationis not set and there is no (or insufficient) historical data for the given channel.
These are the same bounds as returned by
Self::historical_estimated_channel_liquidity_probabilities (but not those returned by
Self::estimated_channel_liquidity_range).
Sourcepub fn live_estimated_payment_success_probability(
&self,
scid: u64,
target: &NodeId,
amount_msat: u64,
params: &ProbabilisticScoringFeeParameters,
) -> Option<f64>
pub fn live_estimated_payment_success_probability( &self, scid: u64, target: &NodeId, amount_msat: u64, params: &ProbabilisticScoringFeeParameters, ) -> Option<f64>
Query the probability of payment success sending the given amount_msat over the channel
with scid towards the given target node, based on the live estimated liquidity bounds.
This will return Some for any channel which is present in the NetworkGraph, including
if we have no bound information beside the channel’s capacity.
Sourcepub fn set_scores(&mut self, external_scores: ChannelLiquidities)
pub fn set_scores(&mut self, external_scores: ChannelLiquidities)
Overwrite the scorer state with the given external scores.
Sourcepub fn scores(&self) -> &ChannelLiquidities
pub fn scores(&self) -> &ChannelLiquidities
Returns the current scores.
Trait Implementations§
Source§impl<G: Deref<Target = NetworkGraph<L>>, L: Deref> ReadableArgs<(ProbabilisticScoringDecayParameters, G, L)> for ProbabilisticScorer<G, L>
impl<G: Deref<Target = NetworkGraph<L>>, L: Deref> ReadableArgs<(ProbabilisticScoringDecayParameters, G, L)> for ProbabilisticScorer<G, L>
Source§fn read<R: Read>(
r: &mut R,
args: (ProbabilisticScoringDecayParameters, G, L),
) -> Result<Self, DecodeError>
fn read<R: Read>( r: &mut R, args: (ProbabilisticScoringDecayParameters, G, L), ) -> Result<Self, DecodeError>
Self in from the given Read.Source§impl<G: Deref<Target = NetworkGraph<L>>, L: Deref> ScoreLookUp for ProbabilisticScorer<G, L>
impl<G: Deref<Target = NetworkGraph<L>>, L: Deref> ScoreLookUp for ProbabilisticScorer<G, L>
Source§type ScoreParams = ProbabilisticScoringFeeParameters
type ScoreParams = ProbabilisticScoringFeeParameters
Source§fn channel_penalty_msat(
&self,
candidate: &CandidateRouteHop<'_>,
usage: ChannelUsage,
score_params: &ProbabilisticScoringFeeParameters,
) -> u64
fn channel_penalty_msat( &self, candidate: &CandidateRouteHop<'_>, usage: ChannelUsage, score_params: &ProbabilisticScoringFeeParameters, ) -> u64
send_amt_msat through the
given channel in the direction from source to target. Read moreSource§impl<G: Deref<Target = NetworkGraph<L>>, L: Deref> ScoreUpdate for ProbabilisticScorer<G, L>
impl<G: Deref<Target = NetworkGraph<L>>, L: Deref> ScoreUpdate for ProbabilisticScorer<G, L>
Source§fn payment_path_failed(
&mut self,
path: &Path,
short_channel_id: u64,
duration_since_epoch: Duration,
)
fn payment_path_failed( &mut self, path: &Path, short_channel_id: u64, duration_since_epoch: Duration, )
Source§fn payment_path_successful(
&mut self,
path: &Path,
duration_since_epoch: Duration,
)
fn payment_path_successful( &mut self, path: &Path, duration_since_epoch: Duration, )
Source§fn probe_failed(
&mut self,
path: &Path,
short_channel_id: u64,
duration_since_epoch: Duration,
)
fn probe_failed( &mut self, path: &Path, short_channel_id: u64, duration_since_epoch: Duration, )
Source§fn probe_successful(&mut self, path: &Path, duration_since_epoch: Duration)
fn probe_successful(&mut self, path: &Path, duration_since_epoch: Duration)
Source§fn time_passed(&mut self, duration_since_epoch: Duration)
fn time_passed(&mut self, duration_since_epoch: Duration)
lightning-background-processor crate).