Skip to content
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

Separate tlv decoding from content validation #2414

Merged
merged 5 commits into from Sep 12, 2022

Conversation

t-bast
Copy link
Member

@t-bast t-bast commented Sep 7, 2022

When decoding a tlv stream, we previously also validated the stream's content at decoding time. This was a layer violation, as checking that specific tlvs are present in a stream is not an encoding concern.

This was somewhat fine when we only had very basic validation (presence or absence of specific tlvs), but blinded paths substantially changed that because one of the tlvs must be decrypted to yield another tlv stream that also needs to have its content validated. Our validation thus became incomplete, since it didn't decrypt the encrypted_recipient_data tlv to validate its own tlv contents.

This forced us to have an overly complex trait hierarchy in PaymentOnion.scala and expose a blinding key in classes that shouldn't care about whether blinding is used or not.

We now decouple that into two distinct steps:

  • codecs simply return tlv streams and verify that tlvs are correctly encoded
  • business logic case classes (such as ChannelRelayPayload) should be instantiated with a new validate method that takes tlv streams and verifies mandatory/forbidden tlvs

This lets us greatly simplify the trait hierarchy and deal with case class that only contain fully decrypted and valid data.

ℹ️ note to reviewers: I recommend starting with the changes in PaymentOnion.scala and PaymentPacket.scala, as they contain the gist of the change. The other changes are simply replicating this same strategy to other codecs and fixing the build and tests.

When decoding a tlv stream, we previously also validated the
stream's content at decoding time. This was a layer violation,
as checking that specific tlvs are present in a stream is not
an encoding concern.

This was somewhat fine when we only had very basic validation
(presence or absence of specific tlvs), but blinded paths
substantially changed that because one of the tlvs must be
decrypted to yield another tlv stream that also needs to have
its content validated.

This forced us to have an overly complex trait hierarchy in
PaymentOnion.scala and expose a blinding key in classes that
shouldn't care about whether blinding is used or not.

We now decouple that into two distinct steps:

* codecs simply return tlv streams and verify that tlvs are
  correctly encoded
* business logic case classes (such as ChannelRelayPayload)
  should be instantiated with a new `validate` method that
  takes tlv streams and verifies mandatory/forbidden tlvs

This lets us greatly simplify the trait hierarchy and deal
with case class that only contain fully decrypted and valid
data.
There was redundancy in the wrong places: route blinding codec tests were
testing route blinding decryption and were missing content validation.

We also change the behavior of the route blinding decode method to return
the blinding override when present, instead of letting higher level
components duplicate that logic.
@t-bast t-bast force-pushed the separate-tlv-decode-validation branch from 98cac21 to 214b020 Compare September 8, 2022 08:36
@t-bast t-bast marked this pull request as ready for review September 8, 2022 08:37
Copy link
Member

@pm47 pm47 left a comment

Choose a reason for hiding this comment

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

LGTM! Feels much cleaner.

Copy link
Member

@thomash-acinq thomash-acinq left a comment

Choose a reason for hiding this comment

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

It's much better indeed. I'm just a bit sad that I will need to rebase my PR on top of this.

@thomash-acinq thomash-acinq merged commit 59f6cda into master Sep 12, 2022
@t-bast t-bast deleted the separate-tlv-decode-validation branch September 12, 2022 11:38
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.

None yet

3 participants