diff --git a/plugins/askrene/mcf.c b/plugins/askrene/mcf.c index 4e48431f2..696b810c7 100644 --- a/plugins/askrene/mcf.c +++ b/plugins/askrene/mcf.c @@ -969,10 +969,15 @@ struct flow **minflow(const tal_t *ctx, params->source = source; params->target = target; params->amount = amount; - params->accuracy = AMOUNT_MSAT(1000); - /* FIXME: params->accuracy = amount_msat_max(amount_msat_div(amount, - * 1000), AMOUNT_MSAT(1)); + /* -> We reduce the granularity of the flow by limiting the subdivision + * of the payment amount into 1000 units of flow. That reduces the + * computational burden for algorithms that depend on it, eg. "capacity + * scaling" and "successive shortest path". + * -> Using Ceil operation instead of Floor so that + * accuracy x 1000 >= amount * */ + params->accuracy = + amount_msat_max(AMOUNT_MSAT(1), amount_msat_div_ceil(amount, 1000)); // template the channel partition into linear arcs params->cap_fraction[0]=0; diff --git a/tests/test_askrene.py b/tests/test_askrene.py index 4c00b411f..01a721e0d 100644 --- a/tests/test_askrene.py +++ b/tests/test_askrene.py @@ -1204,10 +1204,10 @@ def test_real_data(node_factory, bitcoind): # CI, it's slow. if SLOW_MACHINE: limit = 25 - expected = (5, 25, 1567535, 142772, 91) + expected = (6, 25, 1568821, 143649, 91) else: limit = 100 - expected = (9, 96, 6563767, 629671, 91) + expected = (9, 96, 6565467, 630668, 91) fees = {} for n in range(0, limit): @@ -1324,7 +1324,7 @@ def test_real_biases(node_factory, bitcoind): expected = ({1: 6, 2: 6, 4: 7, 8: 12, 16: 14, 32: 19, 64: 25, 100: 25}, 0) else: limit = 100 - expected = ({1: 22, 2: 25, 4: 36, 8: 52, 16: 69, 32: 80, 64: 96, 100: 96}, 0) + expected = ({1: 22, 2: 25, 4: 36, 8: 53, 16: 69, 32: 80, 64: 96, 100: 96}, 0) l1.rpc.askrene_create_layer('biases') num_changed = {} diff --git a/tests/test_xpay.py b/tests/test_xpay.py index ff7179c88..d895e51fd 100644 --- a/tests/test_xpay.py +++ b/tests/test_xpay.py @@ -671,7 +671,7 @@ def test_xpay_bolt12_no_mpp(node_factory, chainparams, deprecations): # Amount needs to be enought that it bothers splitting, but not # so much that it can't pay without mpp. - AMOUNT = 500000000 + AMOUNT = 800000000 # l2 will advertize mpp, l3 won't. l2offer = l2.rpc.offer(AMOUNT, 'test_xpay_bolt12_no_mpp') @@ -686,10 +686,11 @@ def test_xpay_bolt12_no_mpp(node_factory, chainparams, deprecations): assert ret['failed_parts'] == 0 if deprecations: assert ret['successful_parts'] == 2 + assert ret['amount_sent_msat'] == AMOUNT + AMOUNT // 100000 + 2 else: assert ret['successful_parts'] == 1 + assert ret['amount_sent_msat'] == AMOUNT + AMOUNT // 100000 + 1 assert ret['amount_msat'] == AMOUNT - assert ret['amount_sent_msat'] == AMOUNT + AMOUNT // 100000 + 1 def test_xpay_slow_mode(node_factory, bitcoind): @@ -706,18 +707,18 @@ def test_xpay_slow_mode(node_factory, bitcoind): wait_for(lambda: len(l1.rpc.listchannels()['channels']) == 10) # First try an MPP which fails - inv = l5.rpc.invoice(500000000, 'test_xpay_slow_mode_fail', 'test_xpay_slow_mode_fail', preimage='01' * 32)['bolt11'] + inv = l5.rpc.invoice(800000000, 'test_xpay_slow_mode_fail', 'test_xpay_slow_mode_fail', preimage='01' * 32)['bolt11'] l5.rpc.delinvoice('test_xpay_slow_mode_fail', status='unpaid') with pytest.raises(RpcError, match=r"Destination said it doesn't know invoice: incorrect_or_unknown_payment_details"): l1.rpc.xpay(inv) # Now a successful one - inv = l5.rpc.invoice(500000000, 'test_xpay_slow_mode', 'test_xpay_slow_mode', preimage='00' * 32)['bolt11'] + inv = l5.rpc.invoice(800000000, 'test_xpay_slow_mode', 'test_xpay_slow_mode', preimage='00' * 32)['bolt11'] assert l1.rpc.xpay(inv) == {'payment_preimage': '00' * 32, - 'amount_msat': 500000000, - 'amount_sent_msat': 500010002, + 'amount_msat': 800000000, + 'amount_sent_msat': 800016004, 'failed_parts': 0, 'successful_parts': 2} @@ -739,7 +740,7 @@ def test_fail_after_success(node_factory, bitcoind, executor, slow_mode): bitcoind.generate_block(5) wait_for(lambda: len(l1.rpc.listchannels()['channels']) == 10) - inv = l5.rpc.invoice(500000000, 'test_xpay_slow_mode', 'test_xpay_slow_mode', preimage='00' * 32)['bolt11'] + inv = l5.rpc.invoice(800000000, 'test_xpay_slow_mode', 'test_xpay_slow_mode', preimage='00' * 32)['bolt11'] fut = executor.submit(l1.rpc.xpay, invstring=inv, retry_for=0) # Part via l3 is fine. Part via l4 is stuck, so we kill l4 and mine @@ -750,8 +751,8 @@ def test_fail_after_success(node_factory, bitcoind, executor, slow_mode): # Normally, we return as soon as first part succeeds. if slow_mode is False: assert fut.result(TIMEOUT) == {'payment_preimage': '00' * 32, - 'amount_msat': 500000000, - 'amount_sent_msat': 500010002, + 'amount_msat': 800000000, + 'amount_sent_msat': 800016004, 'failed_parts': 0, 'successful_parts': 2} @@ -763,15 +764,15 @@ def test_fail_after_success(node_factory, bitcoind, executor, slow_mode): l1.daemon.wait_for_log(r"UNUSUAL.*Destination accepted partial payment, failed a part \(Error permanent_channel_failure for path ->022d223620a359a47ff7f7ac447c85c46c923da53389221a0054c11c1e3ca31d59->0382ce59ebf18be7d84677c2e35f23294b9992ceca95491fcf8a56c6cb2d9de199->032cf15d1ad9c4a08d26eab1918f732d8ef8fdc6abb9640bf3db174372c491304e, from 022d223620a359a47ff7f7ac447c85c46c923da53389221a0054c11c1e3ca31d59\)") # Could be either way around, check both line = l1.daemon.is_in_log(r"UNUSUAL.*Destination accepted partial payment, failed a part") - assert re.search(r'but accepted only 32000msat of 500000000msat\. Winning\?!', line) or re.search(r'but accepted only 499968000msat of 500000000msat\. Winning\?!', line) + assert re.search(r'but accepted only .* of 800000000msat\. Winning\?!', line) if slow_mode is True: # Now it succeeds, but notes that it only sent one part! res = fut.result(TIMEOUT) # Some variation due to floating point. - assert res['amount_sent_msat'] < 500000000 + assert res['amount_sent_msat'] < 800000000 assert res == {'payment_preimage': '00' * 32, - 'amount_msat': 500000000, + 'amount_msat': 800000000, 'amount_sent_msat': res['amount_sent_msat'], 'failed_parts': 1, 'successful_parts': 1}