diff --git a/plugins/libplugin-pay.c b/plugins/libplugin-pay.c index aa414b2f07b8..fadae6f03eec 100644 --- a/plugins/libplugin-pay.c +++ b/plugins/libplugin-pay.c @@ -1428,7 +1428,8 @@ local_channel_hints_listpeers(struct command *cmd, const char *buffer, spendsats = json_get_member(buffer, channel, "spendable_msat"); scid = json_get_member(buffer, channel, "short_channel_id"); dir = json_get_member(buffer, channel, "direction"); - assert(spendsats != NULL && scid != NULL && dir != NULL); + if(spendsats == NULL || scid == NULL || dir == NULL) + continue; json_to_bool(buffer, connected, &h.enabled); json_to_short_channel_id(buffer, scid, &h.scid.scid); diff --git a/tests/test_pay.py b/tests/test_pay.py index c3d870dab203..b5b4ad824ec5 100644 --- a/tests/test_pay.py +++ b/tests/test_pay.py @@ -3143,3 +3143,37 @@ def test_mpp_adaptive(node_factory, bitcoind): from pprint import pprint pprint(p) pprint(l1.rpc.paystatus(inv)) + + +def test_pay_fail_unconfirmed_channel(node_factory, bitcoind): + ''' + Replicate #3855. + `pay` crash when any direct channel is still + unconfirmed. + ''' + l1, l2 = node_factory.get_nodes(2) + + amount_sat = 10 ** 6 + + # create l2->l1 channel. + l2.fundwallet(amount_sat * 5) + l1.rpc.connect(l2.info['id'], 'localhost', l2.port) + l2.rpc.fundchannel(l1.info['id'], amount_sat * 3) + # channel is still unconfirmed. + + # Attempt to pay from l1 to l2. + # This should fail since the channel capacities are wrong. + invl2 = l2.rpc.invoice(Millisatoshi(amount_sat * 1000), 'i', 'i')['bolt11'] + with pytest.raises(RpcError): + l1.rpc.pay(invl2) + + # Let the channel confirm. + bitcoind.generate_block(6) + sync_blockheight(bitcoind, [l1, l2]) + + # Now give enough capacity so l1 can pay. + invl1 = l1.rpc.invoice(Millisatoshi(amount_sat * 2 * 1000), 'j', 'j')['bolt11'] + l2.rpc.pay(invl1) + + # Now l1 can pay to l2. + l1.rpc.pay(invl2)