routing: add time lock asserts to NewRoute test
This comment extends the unit tests for NewRoute with checks on the total time lock for a route as well as the expected time lock values for every hop along the route.
This commit is contained in:
parent
d4471878df
commit
416f368979
@ -630,36 +630,72 @@ func TestNewRoute(t *testing.T) {
|
|||||||
|
|
||||||
createHop := func(baseFee lnwire.MilliSatoshi,
|
createHop := func(baseFee lnwire.MilliSatoshi,
|
||||||
feeRate lnwire.MilliSatoshi,
|
feeRate lnwire.MilliSatoshi,
|
||||||
capacity btcutil.Amount) (*ChannelHop) {
|
capacity btcutil.Amount,
|
||||||
|
timeLockDelta uint16) (*ChannelHop) {
|
||||||
|
|
||||||
return &ChannelHop {
|
return &ChannelHop {
|
||||||
ChannelEdgePolicy: &channeldb.ChannelEdgePolicy {
|
ChannelEdgePolicy: &channeldb.ChannelEdgePolicy {
|
||||||
Node: &channeldb.LightningNode{},
|
Node: &channeldb.LightningNode{},
|
||||||
FeeProportionalMillionths: feeRate,
|
FeeProportionalMillionths: feeRate,
|
||||||
FeeBaseMSat: baseFee,
|
FeeBaseMSat: baseFee,
|
||||||
|
TimeLockDelta: timeLockDelta,
|
||||||
},
|
},
|
||||||
Capacity: capacity,
|
Capacity: capacity,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
testCases := []struct {
|
testCases := []struct {
|
||||||
name string
|
// name identifies the test case in the test output.
|
||||||
hops []*ChannelHop
|
name string
|
||||||
paymentAmount lnwire.MilliSatoshi
|
|
||||||
expectedFees []lnwire.MilliSatoshi
|
// hops is the list of hops (the route) that gets passed into
|
||||||
expectedTotalAmount lnwire.MilliSatoshi
|
// the call to newRoute.
|
||||||
expectError bool
|
hops []*ChannelHop
|
||||||
expectedErrorCode errorCode
|
|
||||||
|
// 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.
|
// For a single hop payment, no fees are expected to be paid.
|
||||||
name: "single hop",
|
name: "single hop",
|
||||||
paymentAmount: 100000,
|
paymentAmount: 100000,
|
||||||
hops: []*ChannelHop {
|
hops: []*ChannelHop {
|
||||||
createHop(100, 1000, 1000),
|
createHop(100, 1000, 1000, 10),
|
||||||
},
|
},
|
||||||
expectedFees: []lnwire.MilliSatoshi {0},
|
expectedFees: []lnwire.MilliSatoshi {0},
|
||||||
|
expectedTimeLocks: []uint32 {1},
|
||||||
expectedTotalAmount: 100000,
|
expectedTotalAmount: 100000,
|
||||||
|
expectedTotalTimeLock: 1,
|
||||||
}, {
|
}, {
|
||||||
// For a two hop payment, only the fee for the first hop
|
// For a two hop payment, only the fee for the first hop
|
||||||
// needs to be paid. The destination hop does not require
|
// needs to be paid. The destination hop does not require
|
||||||
@ -667,18 +703,20 @@ func TestNewRoute(t *testing.T) {
|
|||||||
name: "two hop",
|
name: "two hop",
|
||||||
paymentAmount: 100000,
|
paymentAmount: 100000,
|
||||||
hops: []*ChannelHop {
|
hops: []*ChannelHop {
|
||||||
createHop(0, 1000, 1000),
|
createHop(0, 1000, 1000, 10),
|
||||||
createHop(30, 1000, 1000),
|
createHop(30, 1000, 1000, 5),
|
||||||
},
|
},
|
||||||
expectedFees: []lnwire.MilliSatoshi {130, 0},
|
expectedFees: []lnwire.MilliSatoshi {130, 0},
|
||||||
|
expectedTimeLocks: []uint32 {1, 1},
|
||||||
expectedTotalAmount: 100130,
|
expectedTotalAmount: 100130,
|
||||||
|
expectedTotalTimeLock: 6,
|
||||||
}, {
|
}, {
|
||||||
// Insufficient capacity in first channel when fees are added.
|
// Insufficient capacity in first channel when fees are added.
|
||||||
name: "two hop insufficient",
|
name: "two hop insufficient",
|
||||||
paymentAmount: 100000,
|
paymentAmount: 100000,
|
||||||
hops: []*ChannelHop {
|
hops: []*ChannelHop {
|
||||||
createHop(0, 1000, 100),
|
createHop(0, 1000, 100, 10),
|
||||||
createHop(0, 1000, 1000),
|
createHop(0, 1000, 1000, 5),
|
||||||
},
|
},
|
||||||
expectError: true,
|
expectError: true,
|
||||||
expectedErrorCode: ErrInsufficientCapacity,
|
expectedErrorCode: ErrInsufficientCapacity,
|
||||||
@ -691,12 +729,14 @@ func TestNewRoute(t *testing.T) {
|
|||||||
name: "three hop",
|
name: "three hop",
|
||||||
paymentAmount: 100000,
|
paymentAmount: 100000,
|
||||||
hops: []*ChannelHop {
|
hops: []*ChannelHop {
|
||||||
createHop(0, 10, 1000),
|
createHop(0, 10, 1000, 10),
|
||||||
createHop(0, 10, 1000),
|
createHop(0, 10, 1000, 5),
|
||||||
createHop(0, 10, 1000),
|
createHop(0, 10, 1000, 3),
|
||||||
},
|
},
|
||||||
expectedFees: []lnwire.MilliSatoshi {1, 1, 0},
|
expectedFees: []lnwire.MilliSatoshi {1, 1, 0},
|
||||||
expectedTotalAmount: 100002,
|
expectedTotalAmount: 100002,
|
||||||
|
expectedTimeLocks: []uint32 {4, 1, 1},
|
||||||
|
expectedTotalTimeLock: 9,
|
||||||
}, {
|
}, {
|
||||||
// A three hop payment where the fee of the first hop
|
// A three hop payment where the fee of the first hop
|
||||||
// is slightly higher (11) than the fee at the second 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",
|
name: "three hop with fee carry over",
|
||||||
paymentAmount: 100000,
|
paymentAmount: 100000,
|
||||||
hops: []*ChannelHop {
|
hops: []*ChannelHop {
|
||||||
createHop(0, 10000, 1000),
|
createHop(0, 10000, 1000, 10),
|
||||||
createHop(0, 10000, 1000),
|
createHop(0, 10000, 1000, 5),
|
||||||
createHop(0, 10000, 1000),
|
createHop(0, 10000, 1000, 3),
|
||||||
},
|
},
|
||||||
expectedFees: []lnwire.MilliSatoshi {1010, 1000, 0},
|
expectedFees: []lnwire.MilliSatoshi {1010, 1000, 0},
|
||||||
expectedTotalAmount: 102010,
|
expectedTotalAmount: 102010,
|
||||||
|
expectedTimeLocks: []uint32 {4, 1, 1},
|
||||||
|
expectedTotalTimeLock: 9,
|
||||||
}, {
|
}, {
|
||||||
// A three hop payment where the fee policies of the first and
|
// A three hop payment where the fee policies of the first and
|
||||||
// second hop are just high enough to show the fee carry over
|
// 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",
|
name: "three hop with minimal fees for carry over",
|
||||||
paymentAmount: 100000,
|
paymentAmount: 100000,
|
||||||
hops: []*ChannelHop {
|
hops: []*ChannelHop {
|
||||||
createHop(0, 10000, 1000),
|
createHop(0, 10000, 1000, 10),
|
||||||
|
|
||||||
// First hop charges 0.1% so the second hop fee
|
// First hop charges 0.1% so the second hop fee
|
||||||
// should show up in the first hop fee as 1 msat
|
// should show up in the first hop fee as 1 msat
|
||||||
// extra.
|
// extra.
|
||||||
createHop(0, 1000, 1000),
|
createHop(0, 1000, 1000, 5),
|
||||||
|
|
||||||
// Second hop charges a fixed 1000 msat.
|
// Second hop charges a fixed 1000 msat.
|
||||||
createHop(1000, 0, 1000),
|
createHop(1000, 0, 1000, 3),
|
||||||
},
|
},
|
||||||
expectedFees: []lnwire.MilliSatoshi {101, 1000, 0},
|
expectedFees: []lnwire.MilliSatoshi {101, 1000, 0},
|
||||||
expectedTotalAmount: 101101,
|
expectedTotalAmount: 101101,
|
||||||
|
expectedTimeLocks: []uint32 {4, 1, 1},
|
||||||
|
expectedTotalTimeLock: 9,
|
||||||
} }
|
} }
|
||||||
|
|
||||||
for _, testCase := range testCases {
|
for _, testCase := range testCases {
|
||||||
@ -739,7 +783,7 @@ func TestNewRoute(t *testing.T) {
|
|||||||
testCase.expectedTotalAmount,
|
testCase.expectedTotalAmount,
|
||||||
route.TotalAmount)
|
route.TotalAmount)
|
||||||
}
|
}
|
||||||
|
|
||||||
for i := 0; i < len(testCase.expectedFees); i++ {
|
for i := 0; i < len(testCase.expectedFees); i++ {
|
||||||
if testCase.expectedFees[i] !=
|
if testCase.expectedFees[i] !=
|
||||||
route.Hops[i].Fee {
|
route.Hops[i].Fee {
|
||||||
@ -750,6 +794,31 @@ func TestNewRoute(t *testing.T) {
|
|||||||
route.Hops[i].Fee)
|
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) {
|
t.Run(testCase.name, func(t *testing.T) {
|
||||||
|
Loading…
Reference in New Issue
Block a user