Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 8 additions & 7 deletions lightningd/pay.c
Original file line number Diff line number Diff line change
Expand Up @@ -588,20 +588,21 @@ void payment_failed(struct lightningd *ld,
onion_wire_name(fail->failcode));
failstr = localfail;
pay_errcode = PAY_TRY_OTHER_ROUTE;
} else if (payment->path_secrets == NULL) {
/* This was a payment initiated with `sendonion`/`injectonionmessage`, we therefore
* don't have the path secrets and cannot decode the error
* onion. We hand it to the user. */
pay_errcode = PAY_UNPARSEABLE_ONION;
fail = NULL;
failstr = NULL;
} else if (failmsg) {
/* This can happen when a direct peer told channeld it's a
* malformed onion using update_fail_malformed_htlc. */
failstr = "local failure";
origin_index = 0;
pay_errcode = PAY_TRY_OTHER_ROUTE;
goto use_failmsg;
} else if (payment->path_secrets == NULL) {
/* This was a payment initiated with `sendonion`/`injectonionmessage`, we therefore
* don't have the path secrets and cannot decode the error
* onion. We hand it to the user. */
assert(failonion != NULL);
pay_errcode = PAY_UNPARSEABLE_ONION;
fail = NULL;
failstr = NULL;
} else {
/* Must be normal remote fail with an onion-wrapped error. */
failstr = "reply from remote";
Expand Down
27 changes: 24 additions & 3 deletions tests/test_misc.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,11 @@
from threading import Event
from pyln.testing.utils import (
TIMEOUT, VALGRIND, sync_blockheight, only_one,
wait_for, TailableProc, env, mine_funding_to_announce
wait_for, TailableProc, env, mine_funding_to_announce,
)
from utils import (
account_balance, scriptpubkey_addr, check_coin_moves, first_scid
account_balance, scriptpubkey_addr, check_coin_moves, first_scid,
serialize_payload_tlv, serialize_payload_final_tlv,
)

import copy
Expand Down Expand Up @@ -2120,7 +2121,7 @@ def test_bad_onion(node_factory, bitcoind):

def test_bad_onion_immediate_peer(node_factory, bitcoind):
"""Test that we handle the malformed msg when we're the origin"""
l1, l2 = node_factory.line_graph(2, opts={'dev-fail-process-onionpacket': None})
l1, l2 = node_factory.line_graph(2, opts=[{}, {'dev-fail-process-onionpacket': None}])

inv = l2.rpc.invoice(123000, 'test_bad_onion_immediate_peer', 'description')
route = l1.rpc.getroute(l2.info['id'], 123000, 1)['route']
Expand All @@ -2137,6 +2138,26 @@ def test_bad_onion_immediate_peer(node_factory, bitcoind):
WIRE_INVALID_ONION_HMAC = 0x8000 | 0x4000 | 5
assert err.value.error['data']['failcode'] == WIRE_INVALID_ONION_HMAC

# Same, but using injectpaymentonion with corrupt onion.
blockheight = l1.rpc.getinfo()['blockheight']
hops = [{'pubkey': l1.info['id'],
'payload': serialize_payload_tlv(123000, 18 + 6, first_scid(l1, l2), blockheight).hex()},
{'pubkey': l2.info['id'],
'payload': serialize_payload_final_tlv(123000, 18, 123000, blockheight, inv['payment_secret']).hex()}]
onion = l1.rpc.createonion(hops=hops, assocdata=inv['payment_hash'])

with pytest.raises(RpcError) as err:
l1.rpc.injectpaymentonion(onion=onion['onion'],
payment_hash=inv['payment_hash'],
amount_msat=123000,
cltv_expiry=blockheight + 18 + 6,
partid=1,
groupid=0)
# FIXME: PAY_INJECTPAYMENTONION_FAILED = 218
PAY_INJECTPAYMENTONION_FAILED = 218
assert err.value.error['code'] == PAY_INJECTPAYMENTONION_FAILED
assert 'onionreply' in err.value.error['data']


def test_newaddr(node_factory, chainparams):
l1 = node_factory.get_node()
Expand Down
Loading