Browse Source

pay: respect maxfeepercent when choosing a shadow route

And the percentage of the initial amount, not the constently increasing
one !

Changelog-Fixed: pay: we now respect maxfeepercent, even for tiny amounts.
Signed-off-by: Antoine Poinsot <darosior@protonmail.com>
nifty/pset-pre
Antoine Poinsot 5 years ago
committed by Rusty Russell
parent
commit
4bb7b4621f
  1. 17
      plugins/pay.c
  2. 1
      tests/test_pay.py

17
plugins/pay.c

@ -85,6 +85,8 @@ struct pay_command {
/* How much we're paying, and what riskfactor for routing. */ /* How much we're paying, and what riskfactor for routing. */
struct amount_msat msat; struct amount_msat msat;
/* Blank amount to pay, without fees and shadow route(s). */
struct amount_msat initial_msat;
/* riskfactor 12.345% -> riskfactor_millionths = 12345000 */ /* riskfactor 12.345% -> riskfactor_millionths = 12345000 */
u64 riskfactor_millionths; u64 riskfactor_millionths;
unsigned int final_cltv; unsigned int final_cltv;
@ -1046,6 +1048,12 @@ static struct command_result *add_shadow_route(struct command *cmd,
size_t i; size_t i;
u64 sample = 0; u64 sample = 0;
struct route_info *route = tal_arr(NULL, struct route_info, 1); struct route_info *route = tal_arr(NULL, struct route_info, 1);
struct amount_msat fees, maxfees;
/* Don't go above this. Note how we use the initial amount to get the percentage
* of the fees, or it would increase with the addition of new shadow routes. */
if (!amount_msat_fee(&maxfees, pc->initial_msat, 0, pc->maxfee_pct_millionths))
plugin_err(cmd->plugin, "Overflow when computing maxfees for "
"shadow routes.");
json_for_each_arr(i, chan, channels) { json_for_each_arr(i, chan, channels) {
u64 v = pseudorand(UINT64_MAX); u64 v = pseudorand(UINT64_MAX);
@ -1068,6 +1076,11 @@ static struct command_result *add_shadow_route(struct command *cmd,
json_to_number(buf, json_get_member(buf, chan, "fee_per_millionth"), json_to_number(buf, json_get_member(buf, chan, "fee_per_millionth"),
&route[0].fee_proportional_millionths); &route[0].fee_proportional_millionths);
if (!amount_msat_fee(&fees, pc->initial_msat, route[0].fee_base_msat,
route[0].fee_proportional_millionths)
|| amount_msat_greater_eq(fees, maxfees))
continue;
best = chan; best = chan;
sample = v; sample = v;
} }
@ -1313,13 +1326,13 @@ static struct command_result *json_pay(struct command *cmd,
return command_fail(cmd, JSONRPC2_INVALID_PARAMS, return command_fail(cmd, JSONRPC2_INVALID_PARAMS,
"msatoshi parameter unnecessary"); "msatoshi parameter unnecessary");
} }
pc->msat = *b11->msat; pc->msat = pc->initial_msat = *b11->msat;
} else { } else {
if (!msat) { if (!msat) {
return command_fail(cmd, JSONRPC2_INVALID_PARAMS, return command_fail(cmd, JSONRPC2_INVALID_PARAMS,
"msatoshi parameter required"); "msatoshi parameter required");
} }
pc->msat = *msat; pc->msat = pc->initial_msat = *msat;
} }
/* Sanity check */ /* Sanity check */

1
tests/test_pay.py

@ -452,7 +452,6 @@ def test_payment_duplicate_uncommitted(node_factory, executor):
fut2.result(10) fut2.result(10)
@pytest.mark.xfail(strict=True)
@unittest.skipIf(not DEVELOPER, "Too slow without --dev-fast-gossip") @unittest.skipIf(not DEVELOPER, "Too slow without --dev-fast-gossip")
def test_pay_maxfee_shadow(node_factory): def test_pay_maxfee_shadow(node_factory):
"""Test that we respect maxfeepercent for shadow routing.""" """Test that we respect maxfeepercent for shadow routing."""

Loading…
Cancel
Save