package routing import ( "testing" "github.com/lightningnetwork/lnd/channeldb" "github.com/lightningnetwork/lnd/lnwire" "github.com/lightningnetwork/lnd/routing/route" ) // TestUnifiedPolicies tests the composition of unified policies for nodes that // have multiple channels between them. func TestUnifiedPolicies(t *testing.T) { source := route.Vertex{1} toNode := route.Vertex{2} fromNode := route.Vertex{3} bandwidthHints := map[uint64]lnwire.MilliSatoshi{} u := newUnifiedPolicies(source, toNode, nil) // Add two channels between the pair of nodes. p1 := channeldb.ChannelEdgePolicy{ FeeProportionalMillionths: 100000, FeeBaseMSat: 30, TimeLockDelta: 60, MessageFlags: lnwire.ChanUpdateOptionMaxHtlc, MaxHTLC: 500, MinHTLC: 100, } p2 := channeldb.ChannelEdgePolicy{ FeeProportionalMillionths: 190000, FeeBaseMSat: 10, TimeLockDelta: 40, MessageFlags: lnwire.ChanUpdateOptionMaxHtlc, MaxHTLC: 400, MinHTLC: 100, } u.addPolicy(fromNode, &p1, 7) u.addPolicy(fromNode, &p2, 7) checkPolicy := func(policy *channeldb.ChannelEdgePolicy, feeBase lnwire.MilliSatoshi, feeRate lnwire.MilliSatoshi, timeLockDelta uint16) { t.Helper() if policy.FeeBaseMSat != feeBase { t.Fatalf("expected fee base %v, got %v", feeBase, policy.FeeBaseMSat) } if policy.TimeLockDelta != timeLockDelta { t.Fatalf("expected fee base %v, got %v", timeLockDelta, policy.TimeLockDelta) } if policy.FeeProportionalMillionths != feeRate { t.Fatalf("expected fee rate %v, got %v", feeRate, policy.FeeProportionalMillionths) } } policy := u.policies[fromNode].getPolicy(50, bandwidthHints) if policy != nil { t.Fatal("expected no policy for amt below min htlc") } policy = u.policies[fromNode].getPolicy(550, bandwidthHints) if policy != nil { t.Fatal("expected no policy for amt above max htlc") } // For 200 sat, p1 yields the highest fee. Use that policy to forward, // because it will also match p2 in case p1 does not have enough // balance. policy = u.policies[fromNode].getPolicy(200, bandwidthHints) checkPolicy( policy, p1.FeeBaseMSat, p1.FeeProportionalMillionths, p1.TimeLockDelta, ) // For 400 sat, p2 yields the highest fee. Use that policy to forward, // because it will also match p1 in case p2 does not have enough // balance. In order to match p1, it needs to have p1's time lock delta. policy = u.policies[fromNode].getPolicy(400, bandwidthHints) checkPolicy( policy, p2.FeeBaseMSat, p2.FeeProportionalMillionths, p1.TimeLockDelta, ) }