mirror of
https://github.com/lightningnetwork/lnd.git
synced 2025-01-18 05:13:36 +01:00
routing: add probability estimator interface
We introduce a probability `Estimator` interface which is implemented by the current apriori probability estimator. A second implementation, the bimodal probability estimator follows.
This commit is contained in:
parent
b0a998af8d
commit
b8c6227383
@ -2,6 +2,7 @@ package routing
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"math"
|
||||
"time"
|
||||
|
||||
@ -45,6 +46,10 @@ const (
|
||||
// capacityCutoffFraction, but a smooth smearing such that some residual
|
||||
// probability is left when spending the whole amount, see above.
|
||||
capacitySmearingFraction = 0.1
|
||||
|
||||
// AprioriEstimatorName is used to identify the apriori probability
|
||||
// estimator.
|
||||
AprioriEstimatorName = "apriori"
|
||||
)
|
||||
|
||||
var (
|
||||
@ -81,6 +86,7 @@ type AprioriConfig struct {
|
||||
AprioriWeight float64
|
||||
}
|
||||
|
||||
// validate checks the configuration of the estimator for allowed values.
|
||||
func (p AprioriConfig) validate() error {
|
||||
if p.PenaltyHalfLife < 0 {
|
||||
return ErrInvalidHalflife
|
||||
@ -97,8 +103,24 @@ func (p AprioriConfig) validate() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// DefaultAprioriConfig returns the default configuration for the estimator.
|
||||
func DefaultAprioriConfig() AprioriConfig {
|
||||
return AprioriConfig{
|
||||
PenaltyHalfLife: DefaultPenaltyHalfLife,
|
||||
AprioriHopProbability: DefaultAprioriHopProbability,
|
||||
AprioriWeight: DefaultAprioriWeight,
|
||||
}
|
||||
}
|
||||
|
||||
// AprioriEstimator returns node and pair probabilities based on historical
|
||||
// payment results.
|
||||
// payment results. It uses a preconfigured success probability value for
|
||||
// untried hops (AprioriHopProbability) and returns a high success probability
|
||||
// for hops that could previously conduct a payment (prevSuccessProbability).
|
||||
// Successful edges are retried until proven otherwise. Recently failed hops are
|
||||
// penalized by an exponential time decay (PenaltyHalfLife), after which they
|
||||
// are reconsidered for routing. If information was learned about a forwarding
|
||||
// node, the information is taken into account to estimate a per node
|
||||
// probability that mixes with the a priori probability (AprioriWeight).
|
||||
type AprioriEstimator struct {
|
||||
// AprioriConfig contains configuration options for our estimator.
|
||||
AprioriConfig
|
||||
@ -108,6 +130,36 @@ type AprioriEstimator struct {
|
||||
prevSuccessProbability float64
|
||||
}
|
||||
|
||||
// NewAprioriEstimator creates a new AprioriEstimator.
|
||||
func NewAprioriEstimator(cfg AprioriConfig) (*AprioriEstimator, error) {
|
||||
if err := cfg.validate(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &AprioriEstimator{
|
||||
AprioriConfig: cfg,
|
||||
prevSuccessProbability: prevSuccessProbability,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// Compile-time checks that interfaces are implemented.
|
||||
var _ Estimator = (*AprioriEstimator)(nil)
|
||||
var _ estimatorConfig = (*AprioriConfig)(nil)
|
||||
|
||||
// Config returns the estimator's configuration.
|
||||
func (p *AprioriEstimator) Config() estimatorConfig {
|
||||
return p.AprioriConfig
|
||||
}
|
||||
|
||||
// String returns the estimator's configuration as a string representation.
|
||||
func (p *AprioriEstimator) String() string {
|
||||
return fmt.Sprintf("estimator type: %v, penalty halflife time: %v, "+
|
||||
"apriori hop probability: %v, apriori weight: %v, previous "+
|
||||
"success probability: %v", AprioriEstimatorName,
|
||||
p.PenaltyHalfLife, p.AprioriHopProbability, p.AprioriWeight,
|
||||
p.prevSuccessProbability)
|
||||
}
|
||||
|
||||
// getNodeProbability calculates the probability for connections from a node
|
||||
// that have not been tried before. The results parameter is a list of last
|
||||
// payment results for that node.
|
||||
|
37
routing/probability_estimator.go
Normal file
37
routing/probability_estimator.go
Normal file
@ -0,0 +1,37 @@
|
||||
package routing
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/btcsuite/btcd/btcutil"
|
||||
"github.com/lightningnetwork/lnd/lnwire"
|
||||
"github.com/lightningnetwork/lnd/routing/route"
|
||||
)
|
||||
|
||||
// Estimator estimates the probability to reach a node.
|
||||
type Estimator interface {
|
||||
// PairProbability estimates the probability of successfully traversing
|
||||
// to toNode based on historical payment outcomes for the from node.
|
||||
// Those outcomes are passed in via the results parameter.
|
||||
PairProbability(now time.Time, results NodeResults,
|
||||
toNode route.Vertex, amt lnwire.MilliSatoshi,
|
||||
capacity btcutil.Amount) float64
|
||||
|
||||
// LocalPairProbability estimates the probability of successfully
|
||||
// traversing our own local channels to toNode.
|
||||
LocalPairProbability(now time.Time, results NodeResults,
|
||||
toNode route.Vertex) float64
|
||||
|
||||
// Config returns the estimator's configuration.
|
||||
Config() estimatorConfig
|
||||
|
||||
// String returns the string representation of the estimator's
|
||||
// configuration.
|
||||
String() string
|
||||
}
|
||||
|
||||
// estimatorConfig represents a configuration for a probability estimator.
|
||||
type estimatorConfig interface {
|
||||
// validate checks that all configuration parameters are sane.
|
||||
validate() error
|
||||
}
|
Loading…
Reference in New Issue
Block a user