1
0
Files
electrum/electrum/tests/test_mpp_split.py
2021-02-24 12:54:43 +01:00

80 lines
3.9 KiB
Python

import random
import electrum.mpp_split as mpp_split # side effect for PART_PENALTY
from electrum.lnutil import NoPathFound
from . import ElectrumTestCase
PART_PENALTY = mpp_split.PART_PENALTY
class TestMppSplit(ElectrumTestCase):
def setUp(self):
super().setUp()
# to make tests reproducible:
random.seed(0)
# undo side effect
mpp_split.PART_PENALTY = PART_PENALTY
self.channels_with_funds = {
0: 1_000_000_000,
1: 500_000_000,
2: 302_000_000,
3: 101_000_000,
}
def test_suggest_splits(self):
with self.subTest(msg="do a payment with the maximal amount spendable over a single channel"):
splits = mpp_split.suggest_splits(1_000_000_000, self.channels_with_funds, exclude_single_parts=True)
self.assertEqual({0: 500_000_000, 1: 500_000_000, 2: 0, 3: 0}, splits[0][0])
with self.subTest(msg="do a payment with a larger amount than what is supported by a single channel"):
splits = mpp_split.suggest_splits(1_100_000_000, self.channels_with_funds, exclude_single_parts=True)
self.assertEqual(2, mpp_split.number_nonzero_parts(splits[0][0]))
with self.subTest(msg="do a payment with the maximal amount spendable over all channels"):
splits = mpp_split.suggest_splits(sum(self.channels_with_funds.values()), self.channels_with_funds, exclude_single_parts=True)
self.assertEqual({0: 1_000_000_000, 1: 500_000_000, 2: 302_000_000, 3: 101_000_000}, splits[0][0])
with self.subTest(msg="do a payment with the amount supported by all channels"):
splits = mpp_split.suggest_splits(101_000_000, self.channels_with_funds, exclude_single_parts=False)
for s in splits[:4]:
self.assertEqual(1, mpp_split.number_nonzero_parts(s[0]))
def test_payment_below_min_part_size(self):
amount = mpp_split.MIN_PART_MSAT // 2
splits = mpp_split.suggest_splits(amount, self.channels_with_funds, exclude_single_parts=False)
# we only get four configurations that end up spending the full amount
# in a single channel
self.assertEqual(4, len(splits))
def test_suggest_part_penalty(self):
"""Test is mainly for documentation purposes.
Decreasing the part penalty from 1.0 towards 0.0 leads to an increase
in the number of parts a payment is split. A configuration which has
about equally distributed amounts will result."""
with self.subTest(msg="split payments with intermediate part penalty"):
mpp_split.PART_PENALTY = 1.0
splits = mpp_split.suggest_splits(1_100_000_000, self.channels_with_funds)
self.assertEqual(2, mpp_split.number_nonzero_parts(splits[0][0]))
with self.subTest(msg="split payments with intermediate part penalty"):
mpp_split.PART_PENALTY = 0.3
splits = mpp_split.suggest_splits(1_100_000_000, self.channels_with_funds)
self.assertEqual(3, mpp_split.number_nonzero_parts(splits[0][0]))
with self.subTest(msg="split payments with no part penalty"):
mpp_split.PART_PENALTY = 0.0
splits = mpp_split.suggest_splits(1_100_000_000, self.channels_with_funds)
self.assertEqual(4, mpp_split.number_nonzero_parts(splits[0][0]))
def test_suggest_splits_single_channel(self):
channels_with_funds = {
0: 1_000_000_000,
}
with self.subTest(msg="do a payment with the maximal amount spendable on a single channel"):
splits = mpp_split.suggest_splits(1_000_000_000, channels_with_funds, exclude_single_parts=False)
self.assertEqual({0: 1_000_000_000}, splits[0][0])
with self.subTest(msg="test sending an amount greater than what we have available"):
self.assertRaises(NoPathFound, mpp_split.suggest_splits, *(1_100_000_000, channels_with_funds))