diff --git a/routing/pathfind_test.go b/routing/pathfind_test.go index 30ffa87af..52177c593 100644 --- a/routing/pathfind_test.go +++ b/routing/pathfind_test.go @@ -630,36 +630,72 @@ func TestNewRoute(t *testing.T) { createHop := func(baseFee lnwire.MilliSatoshi, feeRate lnwire.MilliSatoshi, - capacity btcutil.Amount) (*ChannelHop) { + capacity btcutil.Amount, + timeLockDelta uint16) (*ChannelHop) { return &ChannelHop { ChannelEdgePolicy: &channeldb.ChannelEdgePolicy { Node: &channeldb.LightningNode{}, FeeProportionalMillionths: feeRate, FeeBaseMSat: baseFee, + TimeLockDelta: timeLockDelta, }, Capacity: capacity, } } testCases := []struct { - name string - hops []*ChannelHop - paymentAmount lnwire.MilliSatoshi - expectedFees []lnwire.MilliSatoshi - expectedTotalAmount lnwire.MilliSatoshi - expectError bool - expectedErrorCode errorCode + // name identifies the test case in the test output. + name string + + // hops is the list of hops (the route) that gets passed into + // the call to newRoute. + hops []*ChannelHop + + // paymentAmount is the amount that is send into the route + // indicated by hops. + paymentAmount lnwire.MilliSatoshi + + // expectedFees is a list of fees that every hop is expected + // to charge for forwarding. + expectedFees []lnwire.MilliSatoshi + + // expectedTimeLocks is a list of time lock values that every + // hop is expected to specify in its outgoing HTLC. The time + // lock values in this list are relative to the current block + // height. + expectedTimeLocks []uint32 + + // expectedTotalAmount is the total amount that is expected to + // be returned from newRoute. This amount should include all + // the fees to be paid to intermediate hops. + expectedTotalAmount lnwire.MilliSatoshi + + // expectedTotalTimeLock is the time lock that is expected to + // be returned from newRoute. This is the time lock that should + // be specified in the HTLC that is sent by the source node. + // expectedTotalTimeLock is relative to the current block height. + expectedTotalTimeLock uint32 + + // expectError indicates whether the newRoute call is expected + // to fail or succeed. + expectError bool + + // expectedErrorCode indicates the expected error code when + // expectError is true. + expectedErrorCode errorCode } { { // For a single hop payment, no fees are expected to be paid. name: "single hop", paymentAmount: 100000, hops: []*ChannelHop { - createHop(100, 1000, 1000), + createHop(100, 1000, 1000, 10), }, expectedFees: []lnwire.MilliSatoshi {0}, + expectedTimeLocks: []uint32 {1}, expectedTotalAmount: 100000, + expectedTotalTimeLock: 1, }, { // For a two hop payment, only the fee for the first hop // needs to be paid. The destination hop does not require @@ -667,18 +703,20 @@ func TestNewRoute(t *testing.T) { name: "two hop", paymentAmount: 100000, hops: []*ChannelHop { - createHop(0, 1000, 1000), - createHop(30, 1000, 1000), + createHop(0, 1000, 1000, 10), + createHop(30, 1000, 1000, 5), }, expectedFees: []lnwire.MilliSatoshi {130, 0}, + expectedTimeLocks: []uint32 {1, 1}, expectedTotalAmount: 100130, + expectedTotalTimeLock: 6, }, { // Insufficient capacity in first channel when fees are added. name: "two hop insufficient", paymentAmount: 100000, hops: []*ChannelHop { - createHop(0, 1000, 100), - createHop(0, 1000, 1000), + createHop(0, 1000, 100, 10), + createHop(0, 1000, 1000, 5), }, expectError: true, expectedErrorCode: ErrInsufficientCapacity, @@ -691,12 +729,14 @@ func TestNewRoute(t *testing.T) { name: "three hop", paymentAmount: 100000, hops: []*ChannelHop { - createHop(0, 10, 1000), - createHop(0, 10, 1000), - createHop(0, 10, 1000), + createHop(0, 10, 1000, 10), + createHop(0, 10, 1000, 5), + createHop(0, 10, 1000, 3), }, expectedFees: []lnwire.MilliSatoshi {1, 1, 0}, expectedTotalAmount: 100002, + expectedTimeLocks: []uint32 {4, 1, 1}, + expectedTotalTimeLock: 9, }, { // A three hop payment where the fee of the first hop // is slightly higher (11) than the fee at the second hop, @@ -704,12 +744,14 @@ func TestNewRoute(t *testing.T) { name: "three hop with fee carry over", paymentAmount: 100000, hops: []*ChannelHop { - createHop(0, 10000, 1000), - createHop(0, 10000, 1000), - createHop(0, 10000, 1000), + createHop(0, 10000, 1000, 10), + createHop(0, 10000, 1000, 5), + createHop(0, 10000, 1000, 3), }, expectedFees: []lnwire.MilliSatoshi {1010, 1000, 0}, expectedTotalAmount: 102010, + expectedTimeLocks: []uint32 {4, 1, 1}, + expectedTotalTimeLock: 9, }, { // A three hop payment where the fee policies of the first and // second hop are just high enough to show the fee carry over @@ -717,18 +759,20 @@ func TestNewRoute(t *testing.T) { name: "three hop with minimal fees for carry over", paymentAmount: 100000, hops: []*ChannelHop { - createHop(0, 10000, 1000), + createHop(0, 10000, 1000, 10), // First hop charges 0.1% so the second hop fee // should show up in the first hop fee as 1 msat // extra. - createHop(0, 1000, 1000), + createHop(0, 1000, 1000, 5), // Second hop charges a fixed 1000 msat. - createHop(1000, 0, 1000), + createHop(1000, 0, 1000, 3), }, expectedFees: []lnwire.MilliSatoshi {101, 1000, 0}, expectedTotalAmount: 101101, + expectedTimeLocks: []uint32 {4, 1, 1}, + expectedTotalTimeLock: 9, } } for _, testCase := range testCases { @@ -739,7 +783,7 @@ func TestNewRoute(t *testing.T) { testCase.expectedTotalAmount, route.TotalAmount) } - + for i := 0; i < len(testCase.expectedFees); i++ { if testCase.expectedFees[i] != route.Hops[i].Fee { @@ -750,6 +794,31 @@ func TestNewRoute(t *testing.T) { route.Hops[i].Fee) } } + + expectedTimeLockHeight := startingHeight + + testCase.expectedTotalTimeLock + + if route.TotalTimeLock != expectedTimeLockHeight { + + t.Errorf("Expected total time lock to be %v" + + ", but got %v instead", + expectedTimeLockHeight, + route.TotalTimeLock) + } + + for i := 0; i < len(testCase.expectedTimeLocks); i++ { + expectedTimeLockHeight := startingHeight + + testCase.expectedTimeLocks[i] + + if expectedTimeLockHeight != + route.Hops[i].OutgoingTimeLock { + + t.Errorf("Expected time lock for hop " + + "%v to be %v, but got %v instead", + i, expectedTimeLockHeight, + route.Hops[i].OutgoingTimeLock) + } + } } t.Run(testCase.name, func(t *testing.T) {