Skip to content

Allow duplicate-payment_hash HTLCs for HTLC forwards #167

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Sep 12, 2018

Conversation

TheBlueMatt
Copy link
Collaborator

This is required by BOLT 2 to ensure that no attacker can simply
relay every public node a duplicate-payment_hash HTLC for each HTLC
it receives to deduce where an HTLC came from.

Note that this makes the claim logic much less incentive-compatible
as we will not claim all available HTLCs with the same payment_hash
even if we know the preimage! This is OK because, most likely, any
attackers trying to map the network will use small-value payments
and, hopefully, we will move away from constant hashes across an
entire payment at some point in the near future.

This further simplifies the payment transition state a bit, so
hopefully at least we got some readability out of all of this.

This isnt as simplifying as I'd hoped, but still increases
compile-time checking, which is nice, and removes one of two
panic!()s.
/// Added by remote, to be included in next local commitment tx.
/// Implies HTLCOutput::outbound: false
RemoteAnnounced,
/// Included in a received commitment_signed message (implying we've revoke_and_ack'ed it), but
/// the remote side hasn't yet revoked their previous state, which we need them to do before we
/// accept this HTLC. Implies AwaitingRemoteRevoke.
/// We also have not yet included this HTLC in a commitment_signed message, and are waiting on
/// a remote revoke_and_ack on a previous state before we can do so.
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It wasn't a change but maybe a clearer comment on this one or AwaitingRemoteRevokeToAnnounce could be better, "which we need them to do before we apply its HTLC on our commitment tx" ? To signal that sending a HTLC in commitment_signed it's the same that applying it on our commitment tx, that we only do when we received remote revoke_and_ack

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, I'm not 100% sure what you're suggesting here, but as its not a change I'm open to a new PR to change it.

/// We hold various information about HTLC relay in the HTLC objects in Channel itself:
///
/// Upon receipt of an HTLC from a peer, we'll give it a PendingHTLCStatus indicating if it should
/// Forward the HTLC with information it will give back to us when it does so, or if it should Fail
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

*forward

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed.

@@ -1823,7 +1768,8 @@ impl ChannelManager {
//TODO: here and below MsgHandleErrInternal, #153 case
return Err(MsgHandleErrInternal::send_err_msg_no_close("Got a message for a channel from the wrong node!", msg.channel_id));
}
chan.update_fail_malformed_htlc(&msg, HTLCFailReason::Reason { failure_code: msg.failure_code, data: Vec::new() }).map_err(|e| MsgHandleErrInternal::from_maybe_close(e))
chan.update_fail_malformed_htlc(&msg, HTLCFailReason::Reason { failure_code: msg.failure_code, data: Vec::new() }).map_err(|e| MsgHandleErrInternal::from_maybe_close(e))?;
Ok(())
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why not give back error here ? we can do it with HTLCSource internally now, right ?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can't fail backwards until revoke_and_ack tells us it is safe to do so, receiving an update_fail_htlc/update_fail_malformed_htlc is really only an indication from the remote side that they intend to fail the HTLC, its really once they've revoked their previous state that we consider it done.

session_priv: SecretKey,
},
/// Used for channel rebalancing
CycledRoute {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I find HTLCSource cleaner but os there edge cases that do we want to prevent with CycledRoute to us ? Not at first glance to me but still wandering..

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I hope not? We can't tell the difference between a payment that went around the network and came back through us (unless we are the source) and two payments that are independant and is just an attempt to deanonymize a payment.

@ariard
Copy link

ariard commented Sep 12, 2018

utACK, have review the whole, nothing shocks me!

This is required by BOLT 2 to ensure that no attacker can simply
relay every public node a duplicate-payment_hash HTLC for each HTLC
it receives to deduce where an HTLC came from.

Note that this makes the claim logic much less incentive-compatible
as we will not claim all available HTLCs with the same payment_hash
even if we know the preimage! This is OK because, most likely, any
attackers trying to map the network will use small-value payments
and, hopefully, we will move away from constant hashes across an
entire payment at some point in the near future.

This further simplifies the payment transition state a bit, so
hopefully at least we got some readability out of all of this
@yuntai
Copy link
Contributor

yuntai commented Oct 12, 2018

Note that this makes the claim logic much less incentive-compatible
as we will not claim all available HTLCs with the same payment_hash
even if we know the preimage! This is OK because, most likely, any
attackers trying to map the network will use small-value payments
and, hopefully, we will move away from constant hashes across an
entire payment at some point in the near future.

Duplicate claims will only happen when the recipient of a payment doesn't care about her privacy (and is also greedy) and issue multiple claims, so no reason to protect her while sacrificing our incentive? (also to cost less to the attackers)

@TheBlueMatt
Copy link
Collaborator Author

Duplicate claims will only happen when the recipient of a payment doesn't care about her privacy (and is also greedy) and issue multiple claims, so no reason to protect her while sacrificing our incentive? (also to cost less to the attackers)

No, any intermediate node can create a duplicate payment, which we would then claim. eg if Alice pays Eve through Bob, Charlie and Dave, Bob may send a payment with the same hash through a number of nodes on the network, including Dave, and if Dave claims all pending HTLCs which have the same hash when Eve gives Dave the preimage, then Bob will learn that the payment Alice sent went through Dave, which they shouldn't be able to learn due to the onion encryption.

@yuntai
Copy link
Contributor

yuntai commented Oct 30, 2018

Thanks, very clear!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants