routing: rename apriori estimator

* we rename the current probability estimator to be the "apriori"
  probability estimator to distinguish from a different implementation
  later
* the AprioriEstimator is exported to later be able to type switch
* getLocalPairProbability -> LocalPairProbabiltiy (later part of an
  exported interface)
* getPairProbability -> getPairProbabiltiy (later part of an exported
  interface)
This commit is contained in:
bitromortac
2022-11-18 10:13:45 +01:00
parent 17d7e84b26
commit b0a998af8d
8 changed files with 40 additions and 41 deletions

View File

@ -472,7 +472,7 @@ func (s *Server) SetMissionControlConfig(ctx context.Context,
error) { error) {
cfg := &routing.MissionControlConfig{ cfg := &routing.MissionControlConfig{
ProbabilityEstimatorCfg: routing.ProbabilityEstimatorCfg{ AprioriConfig: routing.AprioriConfig{
PenaltyHalfLife: time.Duration( PenaltyHalfLife: time.Duration(
req.Config.HalfLifeSeconds, req.Config.HalfLifeSeconds,
) * time.Second, ) * time.Second,

View File

@ -75,7 +75,7 @@ func newIntegratedRoutingContext(t *testing.T) *integratedRoutingContext {
finalExpiry: 40, finalExpiry: 40,
mcCfg: MissionControlConfig{ mcCfg: MissionControlConfig{
ProbabilityEstimatorCfg: ProbabilityEstimatorCfg{ AprioriConfig: AprioriConfig{
PenaltyHalfLife: 30 * time.Minute, PenaltyHalfLife: 30 * time.Minute,
AprioriHopProbability: 0.6, AprioriHopProbability: 0.6,
AprioriWeight: 0.5, AprioriWeight: 0.5,

View File

@ -103,7 +103,7 @@ type MissionControl struct {
// estimator is the probability estimator that is used with the payment // estimator is the probability estimator that is used with the payment
// results that mission control collects. // results that mission control collects.
estimator *probabilityEstimator estimator *AprioriEstimator
sync.Mutex sync.Mutex
@ -116,9 +116,8 @@ type MissionControl struct {
// MissionControlConfig defines parameters that control mission control // MissionControlConfig defines parameters that control mission control
// behaviour. // behaviour.
type MissionControlConfig struct { type MissionControlConfig struct {
// ProbabilityEstimatorConfig is the config we will use for probability // AprioriConfig is the config we will use for probability calculations.
// calculations. AprioriConfig
ProbabilityEstimatorCfg
// MaxMcHistory defines the maximum number of payment results that are // MaxMcHistory defines the maximum number of payment results that are
// held on disk. // held on disk.
@ -135,7 +134,7 @@ type MissionControlConfig struct {
} }
func (c *MissionControlConfig) validate() error { func (c *MissionControlConfig) validate() error {
if err := c.ProbabilityEstimatorCfg.validate(); err != nil { if err := c.AprioriConfig.validate(); err != nil {
return err return err
} }
@ -225,9 +224,9 @@ func NewMissionControl(db kvdb.Backend, self route.Vertex,
return nil, err return nil, err
} }
estimator := &probabilityEstimator{ estimator := &AprioriEstimator{
ProbabilityEstimatorCfg: cfg.ProbabilityEstimatorCfg, AprioriConfig: cfg.AprioriConfig,
prevSuccessProbability: prevSuccessProbability, prevSuccessProbability: prevSuccessProbability,
} }
mc := &MissionControl{ mc := &MissionControl{
@ -284,7 +283,7 @@ func (m *MissionControl) GetConfig() *MissionControlConfig {
defer m.Unlock() defer m.Unlock()
return &MissionControlConfig{ return &MissionControlConfig{
ProbabilityEstimatorCfg: m.estimator.ProbabilityEstimatorCfg, AprioriConfig: m.estimator.AprioriConfig,
MaxMcHistory: m.store.maxRecords, MaxMcHistory: m.store.maxRecords,
McFlushInterval: m.store.flushInterval, McFlushInterval: m.store.flushInterval,
MinFailureRelaxInterval: m.state.minFailureRelaxInterval, MinFailureRelaxInterval: m.state.minFailureRelaxInterval,
@ -309,7 +308,7 @@ func (m *MissionControl) SetConfig(cfg *MissionControlConfig) error {
m.store.maxRecords = cfg.MaxMcHistory m.store.maxRecords = cfg.MaxMcHistory
m.state.minFailureRelaxInterval = cfg.MinFailureRelaxInterval m.state.minFailureRelaxInterval = cfg.MinFailureRelaxInterval
m.estimator.ProbabilityEstimatorCfg = cfg.ProbabilityEstimatorCfg m.estimator.AprioriConfig = cfg.AprioriConfig
return nil return nil
} }
@ -344,10 +343,10 @@ func (m *MissionControl) GetProbability(fromNode, toNode route.Vertex,
// Use a distinct probability estimation function for local channels. // Use a distinct probability estimation function for local channels.
if fromNode == m.selfNode { if fromNode == m.selfNode {
return m.estimator.getLocalPairProbability(now, results, toNode) return m.estimator.LocalPairProbability(now, results, toNode)
} }
return m.estimator.getPairProbability( return m.estimator.PairProbability(
now, results, toNode, amt, capacity, now, results, toNode, amt, capacity,
) )
} }

View File

@ -93,7 +93,7 @@ func (ctx *mcTestContext) restartMc() {
mc, err := NewMissionControl( mc, err := NewMissionControl(
ctx.db, mcTestSelf, ctx.db, mcTestSelf,
&MissionControlConfig{ &MissionControlConfig{
ProbabilityEstimatorCfg: ProbabilityEstimatorCfg{ AprioriConfig: AprioriConfig{
PenaltyHalfLife: testPenaltyHalfLife, PenaltyHalfLife: testPenaltyHalfLife,
AprioriHopProbability: testAprioriHopProbability, AprioriHopProbability: testAprioriHopProbability,
AprioriWeight: testAprioriWeight, AprioriWeight: testAprioriWeight,

View File

@ -53,15 +53,16 @@ var (
// ErrInvalidHopProbability is returned when we get an invalid hop // ErrInvalidHopProbability is returned when we get an invalid hop
// probability. // probability.
ErrInvalidHopProbability = errors.New("hop probability must be in [0;1]") ErrInvalidHopProbability = errors.New("hop probability must be in " +
"[0, 1]")
// ErrInvalidAprioriWeight is returned when we get an apriori weight // ErrInvalidAprioriWeight is returned when we get an apriori weight
// that is out of range. // that is out of range.
ErrInvalidAprioriWeight = errors.New("apriori weight must be in [0;1]") ErrInvalidAprioriWeight = errors.New("apriori weight must be in [0, 1]")
) )
// ProbabilityEstimatorCfg contains configuration for our probability estimator. // AprioriConfig contains configuration for our probability estimator.
type ProbabilityEstimatorCfg struct { type AprioriConfig struct {
// PenaltyHalfLife defines after how much time a penalized node or // PenaltyHalfLife defines after how much time a penalized node or
// channel is back at 50% probability. // channel is back at 50% probability.
PenaltyHalfLife time.Duration PenaltyHalfLife time.Duration
@ -80,7 +81,7 @@ type ProbabilityEstimatorCfg struct {
AprioriWeight float64 AprioriWeight float64
} }
func (p ProbabilityEstimatorCfg) validate() error { func (p AprioriConfig) validate() error {
if p.PenaltyHalfLife < 0 { if p.PenaltyHalfLife < 0 {
return ErrInvalidHalflife return ErrInvalidHalflife
} }
@ -96,12 +97,11 @@ func (p ProbabilityEstimatorCfg) validate() error {
return nil return nil
} }
// probabilityEstimator returns node and pair probabilities based on historical // AprioriEstimator returns node and pair probabilities based on historical
// payment results. // payment results.
type probabilityEstimator struct { type AprioriEstimator struct {
// ProbabilityEstimatorCfg contains configuration options for our // AprioriConfig contains configuration options for our estimator.
// estimator. AprioriConfig
ProbabilityEstimatorCfg
// prevSuccessProbability is the assumed probability for node pairs that // prevSuccessProbability is the assumed probability for node pairs that
// successfully relayed the previous attempt. // successfully relayed the previous attempt.
@ -111,7 +111,7 @@ type probabilityEstimator struct {
// getNodeProbability calculates the probability for connections from a node // getNodeProbability calculates the probability for connections from a node
// that have not been tried before. The results parameter is a list of last // that have not been tried before. The results parameter is a list of last
// payment results for that node. // payment results for that node.
func (p *probabilityEstimator) getNodeProbability(now time.Time, func (p *AprioriEstimator) getNodeProbability(now time.Time,
results NodeResults, amt lnwire.MilliSatoshi, results NodeResults, amt lnwire.MilliSatoshi,
capacity btcutil.Amount) float64 { capacity btcutil.Amount) float64 {
@ -184,7 +184,7 @@ func (p *probabilityEstimator) getNodeProbability(now time.Time,
// a payment result. Weight follows an exponential curve that starts at 1 when // a payment result. Weight follows an exponential curve that starts at 1 when
// the result is fresh and asymptotically approaches zero over time. The rate at // the result is fresh and asymptotically approaches zero over time. The rate at
// which this happens is controlled by the penaltyHalfLife parameter. // which this happens is controlled by the penaltyHalfLife parameter.
func (p *probabilityEstimator) getWeight(age time.Duration) float64 { func (p *AprioriEstimator) getWeight(age time.Duration) float64 {
exp := -age.Hours() / p.PenaltyHalfLife.Hours() exp := -age.Hours() / p.PenaltyHalfLife.Hours()
return math.Pow(2, exp) return math.Pow(2, exp)
} }
@ -219,12 +219,12 @@ func capacityFactor(amt lnwire.MilliSatoshi, capacity btcutil.Amount) float64 {
return 1 - 1/denominator return 1 - 1/denominator
} }
// getPairProbability estimates the probability of successfully traversing to // PairProbability estimates the probability of successfully traversing to
// toNode based on historical payment outcomes for the from node. Those outcomes // toNode based on historical payment outcomes for the from node. Those outcomes
// are passed in via the results parameter. // are passed in via the results parameter.
func (p *probabilityEstimator) getPairProbability( func (p *AprioriEstimator) PairProbability(now time.Time,
now time.Time, results NodeResults, toNode route.Vertex, results NodeResults, toNode route.Vertex, amt lnwire.MilliSatoshi,
amt lnwire.MilliSatoshi, capacity btcutil.Amount) float64 { capacity btcutil.Amount) float64 {
nodeProbability := p.getNodeProbability(now, results, amt, capacity) nodeProbability := p.getNodeProbability(now, results, amt, capacity)
@ -233,9 +233,9 @@ func (p *probabilityEstimator) getPairProbability(
) )
} }
// getLocalPairProbability estimates the probability of successfully traversing // LocalPairProbability estimates the probability of successfully traversing
// our own local channels to toNode. // our own local channels to toNode.
func (p *probabilityEstimator) getLocalPairProbability( func (p *AprioriEstimator) LocalPairProbability(
now time.Time, results NodeResults, toNode route.Vertex) float64 { now time.Time, results NodeResults, toNode route.Vertex) float64 {
// For local channels that have never been tried before, we assume them // For local channels that have never been tried before, we assume them
@ -251,7 +251,7 @@ func (p *probabilityEstimator) getLocalPairProbability(
// calculateProbability estimates the probability of successfully traversing to // calculateProbability estimates the probability of successfully traversing to
// toNode based on historical payment outcomes and a fall-back node probability. // toNode based on historical payment outcomes and a fall-back node probability.
func (p *probabilityEstimator) calculateProbability( func (p *AprioriEstimator) calculateProbability(
now time.Time, results NodeResults, now time.Time, results NodeResults,
nodeProbability float64, toNode route.Vertex, nodeProbability float64, toNode route.Vertex,
amt lnwire.MilliSatoshi) float64 { amt lnwire.MilliSatoshi) float64 {

View File

@ -36,7 +36,7 @@ const (
type estimatorTestContext struct { type estimatorTestContext struct {
t *testing.T t *testing.T
estimator *probabilityEstimator estimator *AprioriEstimator
// results contains a list of last results. Every element in the list // results contains a list of last results. Every element in the list
// corresponds to the last result towards a node. The list index equals // corresponds to the last result towards a node. The list index equals
@ -48,8 +48,8 @@ type estimatorTestContext struct {
func newEstimatorTestContext(t *testing.T) *estimatorTestContext { func newEstimatorTestContext(t *testing.T) *estimatorTestContext {
return &estimatorTestContext{ return &estimatorTestContext{
t: t, t: t,
estimator: &probabilityEstimator{ estimator: &AprioriEstimator{
ProbabilityEstimatorCfg: ProbabilityEstimatorCfg{ AprioriConfig: AprioriConfig{
AprioriHopProbability: aprioriHopProb, AprioriHopProbability: aprioriHopProb,
AprioriWeight: aprioriWeight, AprioriWeight: aprioriWeight,
PenaltyHalfLife: time.Hour, PenaltyHalfLife: time.Hour,
@ -74,7 +74,7 @@ func (c *estimatorTestContext) assertPairProbability(now time.Time,
const tolerance = 0.01 const tolerance = 0.01
p := c.estimator.getPairProbability( p := c.estimator.PairProbability(
now, results, route.Vertex{toNode}, amt, capacity, now, results, route.Vertex{toNode}, amt, capacity,
) )
diff := p - expectedProb diff := p - expectedProb

View File

@ -120,7 +120,7 @@ func createTestCtxFromGraphInstanceAssumeValid(t *testing.T,
} }
mcConfig := &MissionControlConfig{ mcConfig := &MissionControlConfig{
ProbabilityEstimatorCfg: ProbabilityEstimatorCfg{ AprioriConfig: AprioriConfig{
PenaltyHalfLife: time.Hour, PenaltyHalfLife: time.Hour,
AprioriHopProbability: 0.9, AprioriHopProbability: 0.9,
AprioriWeight: 0.5, AprioriWeight: 0.5,

View File

@ -868,7 +868,7 @@ func newServer(cfg *Config, listenAddrs []net.Addr,
// servers, the mission control instance itself can be moved there too. // servers, the mission control instance itself can be moved there too.
routingConfig := routerrpc.GetRoutingConfig(cfg.SubRPCServers.RouterRPC) routingConfig := routerrpc.GetRoutingConfig(cfg.SubRPCServers.RouterRPC)
estimatorCfg := routing.ProbabilityEstimatorCfg{ estimatorCfg := routing.AprioriConfig{
AprioriHopProbability: routingConfig.AprioriHopProbability, AprioriHopProbability: routingConfig.AprioriHopProbability,
PenaltyHalfLife: routingConfig.PenaltyHalfLife, PenaltyHalfLife: routingConfig.PenaltyHalfLife,
AprioriWeight: routingConfig.AprioriWeight, AprioriWeight: routingConfig.AprioriWeight,
@ -877,7 +877,7 @@ func newServer(cfg *Config, listenAddrs []net.Addr,
s.missionControl, err = routing.NewMissionControl( s.missionControl, err = routing.NewMissionControl(
dbs.ChanStateDB, selfNode.PubKeyBytes, dbs.ChanStateDB, selfNode.PubKeyBytes,
&routing.MissionControlConfig{ &routing.MissionControlConfig{
ProbabilityEstimatorCfg: estimatorCfg, AprioriConfig: estimatorCfg,
MaxMcHistory: routingConfig.MaxMcHistory, MaxMcHistory: routingConfig.MaxMcHistory,
McFlushInterval: routingConfig.McFlushInterval, McFlushInterval: routingConfig.McFlushInterval,
MinFailureRelaxInterval: routing.DefaultMinFailureRelaxInterval, MinFailureRelaxInterval: routing.DefaultMinFailureRelaxInterval,