channeldb+routing: expose HTLCs in payment subscriptions

This commit modifies the FetchPayment method to return MPPayment structs
converted from the legacy on-disk format. This allows us to attach the
HTLCs to the events given to clients subscribing to the outcome of an
HTLC.

This commit also bubbles up to the routerrpc/router_server, by
populating HTLCAttempts in the response and extracting the legacy route
field from the HTLCAttempts.
This commit is contained in:
Conner Fromknecht
2019-11-08 03:39:51 -08:00
parent 68916eb4b7
commit 063f24f2ed
6 changed files with 143 additions and 86 deletions

View File

@@ -144,10 +144,13 @@ func TestControlTowerSubscribeSuccess(t *testing.T) {
if result.Preimage != preimg {
t.Fatal("unexpected preimage")
}
if !reflect.DeepEqual(result.Route, &attempt.Route) {
t.Fatalf("unexpected route: %v vs %v",
spew.Sdump(result.Route),
if len(result.HTLCs) != 1 {
t.Fatalf("expected one htlc, got %d", len(result.HTLCs))
}
htlc := result.HTLCs[0]
if !reflect.DeepEqual(htlc.Route, attempt.Route) {
t.Fatalf("unexpected htlc route: %v vs %v",
spew.Sdump(htlc.Route),
spew.Sdump(attempt.Route))
}
@@ -168,6 +171,15 @@ func TestControlTowerSubscribeSuccess(t *testing.T) {
func TestPaymentControlSubscribeFail(t *testing.T) {
t.Parallel()
t.Run("register attempt", func(t *testing.T) {
testPaymentControlSubscribeFail(t, true)
})
t.Run("no register attempt", func(t *testing.T) {
testPaymentControlSubscribeFail(t, false)
})
}
func testPaymentControlSubscribeFail(t *testing.T, registerAttempt bool) {
db, err := initDB()
if err != nil {
t.Fatalf("unable to init db: %v", err)
@@ -176,7 +188,7 @@ func TestPaymentControlSubscribeFail(t *testing.T) {
pControl := NewControlTower(channeldb.NewPaymentControl(db))
// Initiate a payment.
info, _, _, err := genInfo()
info, attempt, _, err := genInfo()
if err != nil {
t.Fatal(err)
}
@@ -192,6 +204,17 @@ func TestPaymentControlSubscribeFail(t *testing.T) {
t.Fatalf("expected subscribe to succeed, but got: %v", err)
}
// Conditionally register the attempt based on the test type. This
// allows us to simulate failing after attempting with an htlc or before
// making any attempts at all.
if registerAttempt {
// Register an attempt.
err = pControl.RegisterAttempt(info.PaymentHash, attempt)
if err != nil {
t.Fatal(err)
}
}
// Mark the payment as failed.
if err := pControl.Fail(info.PaymentHash, channeldb.FailureReasonTimeout); err != nil {
t.Fatal(err)
@@ -223,9 +246,28 @@ func TestPaymentControlSubscribeFail(t *testing.T) {
if result.Success {
t.Fatal("unexpected payment state")
}
if result.Route != nil {
t.Fatal("expected no route")
// There will either be one or zero htlcs depending on whether
// or not the attempt was registered. Assert the correct number
// is present, and the route taken if the attempt was
// registered.
if registerAttempt {
if len(result.HTLCs) != 1 {
t.Fatalf("expected 1 htlc, got: %d",
len(result.HTLCs))
}
htlc := result.HTLCs[0]
if !reflect.DeepEqual(htlc.Route, testRoute) {
t.Fatalf("unexpected htlc route: %v vs %v",
spew.Sdump(htlc.Route),
spew.Sdump(testRoute))
}
} else if len(result.HTLCs) != 0 {
t.Fatalf("expected 0 htlcs, got: %d",
len(result.HTLCs))
}
if result.FailureReason != channeldb.FailureReasonTimeout {
t.Fatal("unexpected failure reason")
}