Skip to content

Commit

Permalink
Merge pull request #3221 from joostjager/queryroutes-mc
Browse files Browse the repository at this point in the history
routing+routerrpc+lnrpc: add option to use mc in queryroutes
  • Loading branch information
Roasbeef authored Jul 19, 2019
2 parents 377b7bf + 541e5f4 commit 02a5408
Show file tree
Hide file tree
Showing 14 changed files with 672 additions and 561 deletions.
13 changes: 9 additions & 4 deletions cmd/lncli/commands.go
Original file line number Diff line number Diff line change
Expand Up @@ -2997,6 +2997,10 @@ var queryRoutesCommand = cli.Command{
Usage: "(optional) number of blocks the last hop has to reveal " +
"the preimage",
},
cli.BoolFlag{
Name: "use_mc",
Usage: "use mission control probabilities",
},
},
Action: actionDecorator(queryRoutes),
}
Expand Down Expand Up @@ -3042,10 +3046,11 @@ func queryRoutes(ctx *cli.Context) error {
}

req := &lnrpc.QueryRoutesRequest{
PubKey: dest,
Amt: amt,
FeeLimit: feeLimit,
FinalCltvDelta: int32(ctx.Int("final_cltv_delta")),
PubKey: dest,
Amt: amt,
FeeLimit: feeLimit,
FinalCltvDelta: int32(ctx.Int("final_cltv_delta")),
UseMissionControl: ctx.Bool("use_mc"),
}

route, err := client.QueryRoutes(ctxb, req)
Expand Down
27 changes: 24 additions & 3 deletions lnrpc/routerrpc/router_backend.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ type RouterBackend struct {
amt lnwire.MilliSatoshi, restrictions *routing.RestrictParams,
finalExpiry ...uint16) (*route.Route, error)

MissionControl *routing.MissionControl
MissionControl MissionControl

// ActiveNetParams are the network parameters of the primary network
// that the route is operating on. This is necessary so we can ensure
Expand All @@ -55,6 +55,22 @@ type RouterBackend struct {
Tower routing.ControlTower
}

// MissionControl defines the mission control dependencies of routerrpc.
type MissionControl interface {
// GetEdgeProbability is expected to return the success probability of a payment
// from fromNode along edge.
GetEdgeProbability(fromNode route.Vertex,
edge routing.EdgeLocator, amt lnwire.MilliSatoshi) float64

// ResetHistory resets the history of MissionControl returning it to a state as
// if no payment attempts have been made.
ResetHistory()

// GetHistorySnapshot takes a snapshot from the current mission control state
// and actual probability estimates.
GetHistorySnapshot() *routing.MissionControlSnapshot
}

// QueryRoutes attempts to query the daemons' Channel Router for a possible
// route to a target destination capable of carrying a specific amount of
// satoshis within the route's flow. The retuned route contains the full
Expand Down Expand Up @@ -151,9 +167,14 @@ func (r *RouterBackend) QueryRoutes(ctx context.Context,
return 0
}

return 1
if !in.UseMissionControl {
return 1
}

return r.MissionControl.GetEdgeProbability(
node, edge, amt,
)
},
PaymentAttemptPenalty: routing.DefaultPaymentAttemptPenalty,
}

// Query the channel router for a possible path to the destination that
Expand Down
33 changes: 32 additions & 1 deletion lnrpc/routerrpc/router_backend_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ import (
const (
destKey = "0286098b97bc843372b4426d4b276cea9aa2f48f0428d6f5b66ae101befc14f8b4"
ignoreNodeKey = "02f274f48f3c0d590449a6776e3ce8825076ac376e470e992246eebc565ef8bb2a"

testMissionControlProb = 0.5
)

var (
Expand All @@ -26,6 +28,15 @@ var (
// TestQueryRoutes asserts that query routes rpc parameters are properly parsed
// and passed onto path finding.
func TestQueryRoutes(t *testing.T) {
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) {
ignoreNodeBytes, err := hex.DecodeString(ignoreNodeKey)
if err != nil {
t.Fatal(err)
Expand Down Expand Up @@ -58,6 +69,7 @@ func TestQueryRoutes(t *testing.T) {
ChannelId: 555,
DirectionReverse: true,
}},
UseMissionControl: useMissionControl,
}

findRoute := func(source, target route.Vertex,
Expand Down Expand Up @@ -92,9 +104,13 @@ func TestQueryRoutes(t *testing.T) {
t.Fatal("expecting 0% probability for ignored node")
}

expectedProb := 1.0
if useMissionControl {
expectedProb = testMissionControlProb
}
if restrictions.ProbabilitySource(route.Vertex{},
routing.EdgeLocator{}, 0,
) != 1 {
) != expectedProb {
t.Fatal("expecting 100% probability")
}

Expand All @@ -111,6 +127,7 @@ func TestQueryRoutes(t *testing.T) {

return 1, nil
},
MissionControl: &mockMissionControl{},
}

resp, err := backend.QueryRoutes(context.Background(), request)
Expand All @@ -121,3 +138,17 @@ func TestQueryRoutes(t *testing.T) {
t.Fatal("expected a single route response")
}
}

type mockMissionControl struct {
}

func (m *mockMissionControl) GetEdgeProbability(fromNode route.Vertex,
edge routing.EdgeLocator, amt lnwire.MilliSatoshi) float64 {
return testMissionControlProb
}

func (m *mockMissionControl) ResetHistory() {}

func (m *mockMissionControl) GetHistorySnapshot() *routing.MissionControlSnapshot {
return nil
}
Loading

0 comments on commit 02a5408

Please sign in to comment.