routing: refine amount scaling

Mission control may have outdated success/failure amounts for node pairs
that have channels with differing capacities. In that case we assume to
still find the liquidity as before and rescale the amounts to the
according range.
This commit is contained in:
bitromortac
2024-11-07 12:06:44 +01:00
parent 5afb0de8a8
commit 07f863a2a5
2 changed files with 44 additions and 12 deletions

View File

@@ -500,24 +500,36 @@ func (p *BimodalEstimator) probabilityFormula(capacityMsat, successAmountMsat,
failAmount = capacity
}
// Mission control may have some outdated values, we correct them here.
// TODO(bitromortac): there may be better decisions to make in these
// cases, e.g., resetting failAmount=cap and successAmount=0.
// Mission control may have some outdated values with regard to the
// current channel capacity between a node pair. This can happen in case
// a large parallel channel was closed or if a channel was downscaled
// and can lead to success and/or failure amounts to be out of the range
// [0, capacity]. We assume that the liquidity situation of the channel
// is similar as before due to flow bias.
// failAmount should be capacity at max.
if failAmount > capacity {
log.Debugf("Correcting failAmount %v to capacity %v",
failAmount, capacity)
// In case we have a large success we need to correct it to be in the
// valid range. We set the success amount close to the capacity, because
// we assume to still be able to send. Any possible failure (that must
// in this case be larger than the capacity) is corrected as well.
if successAmount >= capacity {
log.Debugf("Correcting success amount %s and failure amount "+
"%s to capacity %s", successAmountMsat,
failAmount, capacityMsat)
// We choose the success amount to be one less than the
// capacity, to both fit success and failure amounts into the
// capacity range in a consistent manner.
successAmount = capacity - 1
failAmount = capacity
}
// successAmount should be capacity at max.
if successAmount > capacity {
log.Debugf("Correcting successAmount %v to capacity %v",
successAmount, capacity)
// Having no or only a small success, but a large failure only needs
// adjustment of the failure amount.
if failAmount > capacity {
log.Debugf("Correcting failure amount %s to capacity %s",
failAmountMsat, capacityMsat)
successAmount = capacity
failAmount = capacity
}
// We cannot send more than the fail amount.

View File

@@ -212,6 +212,26 @@ func TestSuccessProbability(t *testing.T) {
amount: largeAmount,
expectedProbability: 0.5,
},
// Larger success and larger failure than the old capacity are
// rescaled to still give a very high success rate.
{
name: "smaller cap, large success/fail",
capacity: capacity,
failAmount: 2*capacity + 1,
successAmount: 2 * capacity,
amount: largeAmount,
expectedProbability: 1.0,
},
// A lower success amount is not rescaled.
{
name: "smaller cap, large fail",
capacity: capacity,
successAmount: smallAmount / 2,
failAmount: 2 * capacity,
amount: smallAmount,
// See "previous success, larger amount".
expectedProbability: 0.851,
},
}
estimator := BimodalEstimator{