From bff937a77cfaca2be6f30126c5a731212fe656c9 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Mon, 20 Jul 2020 14:18:56 +0930 Subject: [PATCH] pay: fix problematic sharing of shadow route data. Because listchannels responses are async, with mpp we can end up fighting over use of the parent's data giving results from incorrect final CLTVs to assertion failures like below: ``` pay: plugins/libplugin-pay.c:1964: shadow_route_listchannels: Assertion `amount_msat_greater_eq(p->constraints.fee_budget, d->constraints.fee_budget)' failed. pay: FATAL SIGNAL 6 (version v0.9.0rc2-11-g29d32e0-modded) 0x563129eb6a15 send_backtrace common/daemon.c:38 0x563129eb6abf crashdump common/daemon.c:51 0x7fe37c8b920f ??? ???:0 0x7fe37c8b918b ??? ???:0 0x7fe37c898858 ??? ???:0 0x7fe37c898728 ??? ???:0 0x7fe37c8a9f35 ??? ???:0 0x563129ea5c63 shadow_route_listchannels plugins/libplugin-pay.c:1964 0x563129e9c56a handle_rpc_reply plugins/libplugin.c:547 0x563129e9cbfa rpc_read_response_one plugins/libplugin.c:662 0x563129e9ccf0 rpc_conn_read_response plugins/libplugin.c:681 0x563129ece660 next_plan ccan/ccan/io/io.c:59 0x563129ecf245 do_plan ccan/ccan/io/io.c:407 0x563129ecf287 io_ready ccan/ccan/io/io.c:417 0x563129ed151f io_loop ccan/ccan/io/poll.c:445 0x563129e9ef03 plugin_main plugins/libplugin.c:1284 0x563129e9b099 main plugins/pay.c:2010 0x7fe37c89a0b2 ??? ???:0 0x563129e9452d ??? ???:0 0xffffffffffffffff ??? ???:0 ``` --- plugins/libplugin-pay.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/plugins/libplugin-pay.c b/plugins/libplugin-pay.c index 5d18f7223..5186632e9 100644 --- a/plugins/libplugin-pay.c +++ b/plugins/libplugin-pay.c @@ -1750,13 +1750,21 @@ REGISTER_PAYMENT_MODIFIER(exemptfee, struct exemptfee_data *, static struct shadow_route_data *shadow_route_init(struct payment *p) { + struct shadow_route_data *d = tal(p, struct shadow_route_data), *pd; + + /* If we're not the root we need to inherit the flags set only on the + * root payment. Since we inherit them at each step it's sufficient to + * do so from our direct parent. */ if (p->parent != NULL) { - return payment_mod_shadowroute_get_data(p->parent); + pd = payment_mod_shadowroute_get_data(p->parent); + d->fuzz_amount = pd->fuzz_amount; +#if DEVELOPER + d->use_shadow = pd->use_shadow; +#endif } else { - struct shadow_route_data *d = tal(p, struct shadow_route_data); d->fuzz_amount = true; - return d; } + return d; } /* Mutual recursion */