From 50bf8eb08999cf7738ad0e0d7db5ca9732124fa0 Mon Sep 17 00:00:00 2001 From: Christian Decker Date: Fri, 3 Jul 2020 17:24:46 +0200 Subject: [PATCH] mpp: Add the presplit MPP modifier Changelog-Added: The MPP presplit modifier splits large payments into 10k satoshi parts to maximize chances of performing the payment and to obfuscate the overall amount being sent. --- plugins/pay.c | 8 +++++++- tests/test_pay.py | 24 ++++++++++++++++++++++++ 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/plugins/pay.c b/plugins/pay.c index 6aa03efd5..ec1404c6b 100644 --- a/plugins/pay.c +++ b/plugins/pay.c @@ -1841,6 +1841,7 @@ struct payment_modifier *paymod_mods[] = { &directpay_pay_mod, &shadowroute_pay_mod, &exemptfee_pay_mod, + &presplit_pay_mod, &routehints_pay_mod, &waitblockheight_pay_mod, &retry_pay_mod, @@ -1861,6 +1862,7 @@ static struct command_result *json_paymod(struct command *cmd, const char *label; unsigned int *retryfor; u64 *riskfactor_millionths; + struct shadow_route_data *shadow_route; #if DEVELOPER bool *use_shadow; #endif @@ -1949,8 +1951,12 @@ static struct command_result *json_paymod(struct command *cmd, p->constraints.cltv_budget = *maxdelay; payment_mod_exemptfee_get_data(p)->amount = *exemptfee; + shadow_route = payment_mod_shadowroute_get_data(p); + + /* This is an MPP enabled pay command, disable amount fuzzing. */ + shadow_route->fuzz_amount = false; #if DEVELOPER - payment_mod_shadowroute_get_data(p)->use_shadow = *use_shadow; + shadow_route->use_shadow = *use_shadow; #endif p->label = tal_steal(p, label); payment_start(p); diff --git a/tests/test_pay.py b/tests/test_pay.py index 43397b473..c350777b3 100644 --- a/tests/test_pay.py +++ b/tests/test_pay.py @@ -3055,3 +3055,27 @@ def test_pay_peer(node_factory): # Next one should take the alternative, but it should still work inv = l2.rpc.invoice(amt.millisatoshis, "final", "final")['bolt11'] l1.rpc.dev_pay(inv, use_shadow=False) + + +def test_mpp_presplit(node_factory): + """Make a rather large payment of 5*10ksat and see it being split. + """ + MPP_TARGET_SIZE = 10**7 # Taken from libpluin-pay.c + amt = 5 * MPP_TARGET_SIZE + + # Assert that the amount we're going to send is indeed larger than our + # split size. + assert(MPP_TARGET_SIZE < amt) + + l1, l2, l3 = node_factory.line_graph( + 3, fundamount=10**8, wait_for_announce=True, + opts={'wumbo': None} + ) + + inv = l3.rpc.invoice(amt, 'lbl', 'desc')['bolt11'] + p = l1.rpc.pay(inv) + + assert(p['parts'] >= 5) + inv = l3.rpc.listinvoices()['invoices'][0] + + assert(inv['msatoshi'] == inv['msatoshi_received'])