Skip to content

Commit 396799a

Browse files
committed
lnpeer: add prefix to forwarding payment_keys.
This prevents collisions with payment_keys to an invoice of ours. Note that this is not defense-in-depth: this commit does NOT prevent a node from releasing the preimage, if it receives a tiny trampoline HTLC to forward for one of its own invoices. Indeed, the namespaced bucket would still enter the SETTLING state. What prevents the attack is the previous commit, and only that.
1 parent 9172b28 commit 396799a

3 files changed

Lines changed: 8 additions & 3 deletions

File tree

electrum/lnpeer.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@
4848
IncompatibleLightningFeatures, ChannelType, LNProtocolWarning, validate_features,
4949
IncompatibleOrInsaneFeatures, ReceivedMPPStatus, ReceivedMPPHtlc,
5050
GossipForwardingMessage, GossipTimestampFilter, channel_id_from_funding_tx,
51-
serialize_htlc_key, Keypair, RecvMPPResolution)
51+
serialize_htlc_key, serialize_trampoline_fwd_key, Keypair, RecvMPPResolution)
5252
from .lntransport import LNTransport, LNTransportBase, LightningPeerConnectionClosed, HandshakeFailed
5353
from .lnmsg import encode_msg, decode_msg, UnknownOptionalMsgType, FailedToParseMsg
5454
from .interface import GracefulDisconnect
@@ -2222,7 +2222,7 @@ def _check_unfulfilled_htlc(
22222222
raise OnionRoutingFailure(code=OnionFailureCode.TEMPORARY_NODE_FAILURE, data=b'')
22232223
if outer_onion_payment_secret:
22242224
# this is a trampoline forwarding htlc, multiple incoming trampoline htlcs can be collected
2225-
payment_key = (payment_hash + outer_onion_payment_secret).hex()
2225+
payment_key = serialize_trampoline_fwd_key(payment_hash, outer_onion_payment_secret)
22262226
return payment_key
22272227
# this is a regular htlc to forward, it will get its own set of size 1 keyed by htlc_key
22282228
# Additional checks required only for forwarding nodes will be done in maybe_forward_htlc().

electrum/lnutil.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,11 @@ def deserialize_htlc_key(htlc_key: str) -> Tuple[bytes, int]:
9393
return bytes.fromhex(scid), int(htlc_id)
9494

9595

96+
def serialize_trampoline_fwd_key(payment_hash: bytes, outer_payment_secret: bytes) -> str:
97+
"""Bucket key for incoming htlcs we are asked to relay as a trampoline node. """
98+
return 'fwd:' + (payment_hash + outer_payment_secret).hex()
99+
100+
96101
@attr.s
97102
class OnlyPubkeyKeypair(StoredObject):
98103
pubkey = attr.ib(type=bytes, converter=hex_to_bytes, repr=bytes_to_hex)

electrum/lnworker.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2958,7 +2958,7 @@ def update_or_create_mpp_with_received_htlc(
29582958
):
29592959
# Payment key creation:
29602960
# * for regular forwarded htlcs -> "scid.hex() + ':%d' % htlc_id" [htlc key]
2961-
# * for trampoline forwarding -> "payment hash + payment secret from outer onion"
2961+
# * for trampoline forwarding -> "fwd:" + (payment hash + payment secret from outer onion).hex()
29622962
# * for final non-trampoline htlcs (we are receiver) -> "payment hash + payment secret from onion"
29632963
# * for final trampoline htlcs (we are receiver) -> 2. step grouping:
29642964
# 1. grouping of htlcs by "payments hash + outer onion payment secret", a 'multi-trampoline mpp part'.

0 commit comments

Comments
 (0)