2019-03-11 11:56:05 +03:00
|
|
|
package routerrpc
|
|
|
|
|
|
|
|
import (
|
|
|
|
"bytes"
|
|
|
|
"context"
|
|
|
|
"encoding/hex"
|
|
|
|
"testing"
|
|
|
|
|
|
|
|
"github.com/btcsuite/btcutil"
|
|
|
|
"github.com/lightningnetwork/lnd/lnwire"
|
|
|
|
"github.com/lightningnetwork/lnd/routing"
|
2019-04-05 18:36:11 +03:00
|
|
|
"github.com/lightningnetwork/lnd/routing/route"
|
2019-03-11 11:56:05 +03:00
|
|
|
|
|
|
|
"github.com/lightningnetwork/lnd/lnrpc"
|
|
|
|
)
|
|
|
|
|
|
|
|
const (
|
|
|
|
destKey = "0286098b97bc843372b4426d4b276cea9aa2f48f0428d6f5b66ae101befc14f8b4"
|
|
|
|
ignoreNodeKey = "02f274f48f3c0d590449a6776e3ce8825076ac376e470e992246eebc565ef8bb2a"
|
2019-06-19 09:29:44 +03:00
|
|
|
|
|
|
|
testMissionControlProb = 0.5
|
2019-03-11 11:56:05 +03:00
|
|
|
)
|
|
|
|
|
|
|
|
var (
|
2019-04-05 18:36:11 +03:00
|
|
|
sourceKey = route.Vertex{1, 2, 3}
|
2019-03-11 11:56:05 +03:00
|
|
|
)
|
|
|
|
|
|
|
|
// TestQueryRoutes asserts that query routes rpc parameters are properly parsed
|
|
|
|
// and passed onto path finding.
|
|
|
|
func TestQueryRoutes(t *testing.T) {
|
2019-06-19 09:29:44 +03:00
|
|
|
t.Run("no mission control", func(t *testing.T) {
|
|
|
|
testQueryRoutes(t, false)
|
|
|
|
})
|
|
|
|
t.Run("with mission control", func(t *testing.T) {
|
|
|
|
testQueryRoutes(t, true)
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
func testQueryRoutes(t *testing.T, useMissionControl bool) {
|
2019-03-11 11:56:05 +03:00
|
|
|
ignoreNodeBytes, err := hex.DecodeString(ignoreNodeKey)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
|
2019-04-05 18:36:11 +03:00
|
|
|
var ignoreNodeVertex route.Vertex
|
2019-03-11 11:56:05 +03:00
|
|
|
copy(ignoreNodeVertex[:], ignoreNodeBytes)
|
|
|
|
|
|
|
|
destNodeBytes, err := hex.DecodeString(destKey)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
|
2019-03-19 13:45:10 +03:00
|
|
|
ignoredEdge := routing.EdgeLocator{
|
|
|
|
ChannelID: 555,
|
|
|
|
Direction: 1,
|
|
|
|
}
|
|
|
|
|
2019-03-11 11:56:05 +03:00
|
|
|
request := &lnrpc.QueryRoutesRequest{
|
|
|
|
PubKey: destKey,
|
|
|
|
Amt: 100000,
|
|
|
|
FinalCltvDelta: 100,
|
|
|
|
FeeLimit: &lnrpc.FeeLimit{
|
|
|
|
Limit: &lnrpc.FeeLimit_Fixed{
|
|
|
|
Fixed: 250,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
IgnoredNodes: [][]byte{ignoreNodeBytes},
|
2019-04-05 18:25:49 +03:00
|
|
|
IgnoredEdges: []*lnrpc.EdgeLocator{{
|
2019-03-11 11:56:05 +03:00
|
|
|
ChannelId: 555,
|
|
|
|
DirectionReverse: true,
|
|
|
|
}},
|
2019-06-19 09:29:44 +03:00
|
|
|
UseMissionControl: useMissionControl,
|
2019-03-11 11:56:05 +03:00
|
|
|
}
|
|
|
|
|
2019-05-07 18:01:01 +03:00
|
|
|
findRoute := func(source, target route.Vertex,
|
2019-03-11 11:56:05 +03:00
|
|
|
amt lnwire.MilliSatoshi, restrictions *routing.RestrictParams,
|
2019-05-07 18:01:01 +03:00
|
|
|
finalExpiry ...uint16) (*route.Route, error) {
|
2019-03-11 11:56:05 +03:00
|
|
|
|
|
|
|
if int64(amt) != request.Amt*1000 {
|
|
|
|
t.Fatal("unexpected amount")
|
|
|
|
}
|
|
|
|
|
|
|
|
if source != sourceKey {
|
|
|
|
t.Fatal("unexpected source key")
|
|
|
|
}
|
|
|
|
|
|
|
|
if !bytes.Equal(target[:], destNodeBytes) {
|
|
|
|
t.Fatal("unexpected target key")
|
|
|
|
}
|
|
|
|
|
|
|
|
if restrictions.FeeLimit != 250*1000 {
|
|
|
|
t.Fatal("unexpected fee limit")
|
|
|
|
}
|
|
|
|
|
2019-03-19 13:45:10 +03:00
|
|
|
if restrictions.ProbabilitySource(route.Vertex{},
|
2019-03-19 19:09:27 +03:00
|
|
|
ignoredEdge, 0,
|
2019-03-19 13:45:10 +03:00
|
|
|
) != 0 {
|
|
|
|
t.Fatal("expecting 0% probability for ignored edge")
|
2019-03-11 11:56:05 +03:00
|
|
|
}
|
|
|
|
|
2019-03-19 13:45:10 +03:00
|
|
|
if restrictions.ProbabilitySource(ignoreNodeVertex,
|
2019-03-19 19:09:27 +03:00
|
|
|
routing.EdgeLocator{}, 0,
|
2019-03-19 13:45:10 +03:00
|
|
|
) != 0 {
|
|
|
|
t.Fatal("expecting 0% probability for ignored node")
|
2019-03-11 11:56:05 +03:00
|
|
|
}
|
|
|
|
|
2019-06-19 09:29:44 +03:00
|
|
|
expectedProb := 1.0
|
|
|
|
if useMissionControl {
|
|
|
|
expectedProb = testMissionControlProb
|
|
|
|
}
|
2019-03-19 13:45:10 +03:00
|
|
|
if restrictions.ProbabilitySource(route.Vertex{},
|
2019-03-19 19:09:27 +03:00
|
|
|
routing.EdgeLocator{}, 0,
|
2019-06-19 09:29:44 +03:00
|
|
|
) != expectedProb {
|
2019-03-19 13:45:10 +03:00
|
|
|
t.Fatal("expecting 100% probability")
|
2019-03-11 11:56:05 +03:00
|
|
|
}
|
|
|
|
|
2019-05-27 13:33:43 +03:00
|
|
|
hops := []*route.Hop{{}}
|
2019-05-15 15:37:58 +03:00
|
|
|
return route.NewRouteFromHops(amt, 144, source, hops)
|
2019-03-11 11:56:05 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
backend := &RouterBackend{
|
|
|
|
MaxPaymentMSat: lnwire.NewMSatFromSatoshis(1000000),
|
2019-05-07 18:01:01 +03:00
|
|
|
FindRoute: findRoute,
|
2019-04-05 18:36:11 +03:00
|
|
|
SelfNode: route.Vertex{1, 2, 3},
|
2019-03-11 11:56:05 +03:00
|
|
|
FetchChannelCapacity: func(chanID uint64) (
|
|
|
|
btcutil.Amount, error) {
|
|
|
|
|
|
|
|
return 1, nil
|
|
|
|
},
|
2019-06-19 09:29:44 +03:00
|
|
|
MissionControl: &mockMissionControl{},
|
2019-03-11 11:56:05 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
resp, err := backend.QueryRoutes(context.Background(), request)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
if len(resp.Routes) != 1 {
|
|
|
|
t.Fatal("expected a single route response")
|
|
|
|
}
|
|
|
|
}
|
2019-06-19 09:29:44 +03:00
|
|
|
|
|
|
|
type mockMissionControl struct {
|
|
|
|
}
|
|
|
|
|
|
|
|
func (m *mockMissionControl) GetEdgeProbability(fromNode route.Vertex,
|
|
|
|
edge routing.EdgeLocator, amt lnwire.MilliSatoshi) float64 {
|
|
|
|
return testMissionControlProb
|
|
|
|
}
|
|
|
|
|
2019-06-26 14:00:35 +03:00
|
|
|
func (m *mockMissionControl) ResetHistory() error {
|
|
|
|
return nil
|
|
|
|
}
|
2019-06-19 09:29:44 +03:00
|
|
|
|
|
|
|
func (m *mockMissionControl) GetHistorySnapshot() *routing.MissionControlSnapshot {
|
|
|
|
return nil
|
|
|
|
}
|