lnd.xprv/routing/integrated_routing_test.go
Joost Jager 29476ec6a3
routing/test: test probability extrapolation
Adds an integrated routing test of probability extrapolation for untried
channels. The larger part of this commit is mock code to simulate the
Lightning Network.

The difference between this test and the existing pathfinding tests, is that
this test focuses on the feedback loop from result interpretation via
mission control updates and probability estimation back to pathfinding.
Improvements like probability extrapolation were previously only
validated by reasoning, while this setup makes it possible to assert the
improvement in a test and guard it for the future.
2020-02-11 14:19:13 +01:00

58 lines
2.0 KiB
Go

package routing
import (
"testing"
)
// TestProbabilityExtrapolation tests that probabilities for tried channels are
// extrapolated to untried channels. This is a way to improve pathfinding
// success by steering away from bad nodes.
func TestProbabilityExtrapolation(t *testing.T) {
ctx := newIntegratedRoutingContext(t)
// Create the following network of nodes:
// source -> expensiveNode (charges routing fee) -> target
// source -> intermediate1 (free routing) -> intermediate(1-10) (free routing) -> target
g := ctx.graph
expensiveNode := newMockNode()
expensiveNode.baseFee = 10000
g.addNode(expensiveNode)
g.addChannel(ctx.source, expensiveNode, 100000)
g.addChannel(ctx.target, expensiveNode, 100000)
intermediate1 := newMockNode()
g.addNode(intermediate1)
g.addChannel(ctx.source, intermediate1, 100000)
for i := 0; i < 10; i++ {
imNode := newMockNode()
g.addNode(imNode)
g.addChannel(imNode, ctx.target, 100000)
g.addChannel(imNode, intermediate1, 100000)
// The channels from intermediate1 all have insufficient balance.
g.nodes[intermediate1.pubkey].channels[imNode.pubkey].balance = 0
}
// It is expected that pathfinding will try to explore the routes via
// intermediate1 first, because those are free. But as failures happen,
// the node probability of intermediate1 will go down in favor of the
// paid route via expensiveNode.
//
// The exact number of attempts required is dependent on mission control
// config. For this test, it would have been enough to only assert that
// we are not trying all routes via intermediate1. However, we do assert
// a specific number of attempts to safe-guard against accidental
// modifications anywhere in the chain of components that is involved in
// this test.
ctx.testPayment(5)
// If we use a static value for the node probability (no extrapolation
// of data from other channels), all ten bad channels will be tried
// first before switching to the paid channel.
ctx.mcCfg.AprioriWeight = 1
ctx.testPayment(11)
}