routing: if MaxShardAmt is set, then use that as a ceiling for our splits

In this commit, we thread through the necessary state to allow users to
set a max shard amount. If this value is set, then this'll effectively
serve as a ceiling for all our split attempts. If we need to split,
we'll first try to use `paymentAmt/2`, if that's bigger than
`MaxShardAmt, then we'll use the latter instead.

Ideally in the future we have a dynamic way to automatically set both
the `MaxShardAmt` as well as `MaxParts` for users. Until then exposing
these two new fields will allow us to experiment with setting them
automatically using the RPC interface, and also give users a bit more
control over how we attempt to route payments, akin to coin control for
on-chain payments.

Fixes #4730
This commit is contained in:
Olaoluwa Osuntokun committed 2021-02-15 19:31:52 -08:00
1 parent 7398e59927
commit b73a6e2c61
4 files changed
+57 -1

No files matched your search

+33
View File
@@ -89,6 +89,7 @@ type mppSendTestCase struct {
graph func(g *mockGraph)
expectedFailure bool
maxParts uint32
maxShardSize btcutil.Amount
}
const (
@@ -208,6 +209,33 @@ var mppTestCases = []mppSendTestCase{
expectedFailure: true,
maxParts: 10,
},
// Test that if maxShardSize is set, then all attempts are below the
// max shard size, yet still sum up to the total payment amount. A
// payment of 30k satoshis with a max shard size of 10k satoshis should
// produce 3 payments of 10k sats each.
{
name: "max shard size clamping",
graph: onePathGraph,
amt: 30_000,
expectedAttempts: 3,
expectedSuccesses: []expectedHtlcSuccess{
{
amt: 10_000,
chans: []uint64{chanSourceIm1, chanIm1Target},
},
{
amt: 10_000,
chans: []uint64{chanSourceIm1, chanIm1Target},
},
{
amt: 10_000,
chans: []uint64{chanSourceIm1, chanIm1Target},
},
},
maxParts: 1000,
maxShardSize: 10_000,
},
}
// TestMppSend tests that a payment can be completed using multiple shards.
@@ -229,6 +257,11 @@ func testMppSend(t *testing.T, testCase *mppSendTestCase) {
ctx.amt = lnwire.NewMSatFromSatoshis(testCase.amt)
if testCase.maxShardSize != 0 {
shardAmt := lnwire.NewMSatFromSatoshis(testCase.maxShardSize)
ctx.maxShardAmt = &shardAmt
}
attempts, err := ctx.testPayment(testCase.maxParts)
switch {
case err == nil && testCase.expectedFailure: