htlcswitch+refactor: continue modularising extractTLVPayload

In this refactor commit, we extract all the steps from extractTLVPayload
that have to do with parsing the payload from the sender and verifying
the presence of various fields from the sender.
This commit is contained in:
Elle Mouton 2024-07-10 10:44:49 +02:00
parent a15e4bb55f
commit 55c25f427f
No known key found for this signature in database
GPG key ID: D7D916376026F177

View file

@ -188,53 +188,20 @@ func (r *sphinxHopIterator) HopPayload() (*Payload, RouteRole, error) {
func extractTLVPayload(r *sphinxHopIterator) (*Payload, RouteRole, error) { func extractTLVPayload(r *sphinxHopIterator) (*Payload, RouteRole, error) {
isFinal := r.processedPacket.Action == sphinx.ExitNode isFinal := r.processedPacket.Action == sphinx.ExitNode
// Extract TLVs from the packet constructor (the sender). // Initial payload parsing and validation
payload, parsed, err := ParseTLVPayload( payload, routeRole, recipientData, err := parseAndValidateSenderPayload(
bytes.NewReader(r.processedPacket.Payload.Payload), r.processedPacket.Payload.Payload, isFinal,
r.blindingKit.UpdateAddBlinding.IsSome(),
) )
if err != nil { if err != nil {
// If we couldn't even parse our payload then we do a
// best-effort of determining our role in a blinded route,
// accepting that we can't know whether we were the introduction
// node (as the payload is not parseable).
routeRole := RouteRoleCleartext
if r.blindingKit.UpdateAddBlinding.IsSome() {
routeRole = RouteRoleRelaying
}
return nil, routeRole, err return nil, routeRole, err
} }
// Now that we've parsed our payload we can determine which role we're // If the payload contained no recipient data, then we can exit now.
// playing in the route. if !recipientData {
_, payloadBlinding := parsed[record.BlindingPointOnionType]
routeRole := NewRouteRole(
r.blindingKit.UpdateAddBlinding.IsSome(), payloadBlinding,
)
// Validate the presence of the various payload fields we received from
// the sender.
if err := ValidateTLVPayload(
parsed, isFinal, r.blindingKit.UpdateAddBlinding.IsSome(),
); err != nil {
return nil, routeRole, err
}
// If there is no encrypted data from the receiver then return the
// payload as is since the forwarding info would have been received
// from the sender.
if payload.encryptedData != nil {
return payload, routeRole, nil return payload, routeRole, nil
} }
// Validate the presence of various fields in the sender payload given
// that we now know that this is a hop with instructions from the
// recipient.
err = ValidatePayloadWithBlinded(isFinal, parsed)
if err != nil {
return payload, routeRole, err
}
// If we had an encrypted data payload present, pull out our forwarding // If we had an encrypted data payload present, pull out our forwarding
// info from the blob. // info from the blob.
fwdInfo, err := r.blindingKit.DecryptAndValidateFwdInfo( fwdInfo, err := r.blindingKit.DecryptAndValidateFwdInfo(
@ -249,6 +216,61 @@ func extractTLVPayload(r *sphinxHopIterator) (*Payload, RouteRole, error) {
return payload, routeRole, nil return payload, routeRole, nil
} }
// parseAndValidateSenderPayload parses the payload bytes received from the
// onion constructor (the sender) and validates that various fields have been
// set. It also uses the presence of a blinding key in either the
// update_add_htlc message or in the payload to determine the RouteRole.
// The RouteRole is returned even if an error is returned. The boolean return
// value indicates that the sender payload includes encrypted data from the
// recipient that should be parsed.
func parseAndValidateSenderPayload(payloadBytes []byte, isFinalHop,
updateAddBlindingSet bool) (*Payload, RouteRole, bool, error) {
// Extract TLVs from the packet constructor (the sender).
payload, parsed, err := ParseTLVPayload(bytes.NewReader(payloadBytes))
if err != nil {
// If we couldn't even parse our payload then we do a
// best-effort of determining our role in a blinded route,
// accepting that we can't know whether we were the introduction
// node (as the payload is not parseable).
routeRole := RouteRoleCleartext
if updateAddBlindingSet {
routeRole = RouteRoleRelaying
}
return nil, routeRole, false, err
}
// Now that we've parsed our payload we can determine which role we're
// playing in the route.
_, payloadBlinding := parsed[record.BlindingPointOnionType]
routeRole := NewRouteRole(updateAddBlindingSet, payloadBlinding)
// Validate the presence of the various payload fields we received from
// the sender.
err = ValidateTLVPayload(parsed, isFinalHop, updateAddBlindingSet)
if err != nil {
return nil, routeRole, false, err
}
// If there is no encrypted data from the receiver then return the
// payload as is since the forwarding info would have been received
// from the sender.
if payload.encryptedData == nil {
return payload, routeRole, false, nil
}
// Validate the presence of various fields in the sender payload given
// that we now know that this is a hop with instructions from the
// recipient.
err = ValidatePayloadWithBlinded(isFinalHop, parsed)
if err != nil {
return payload, routeRole, true, err
}
return payload, routeRole, true, nil
}
// ExtractErrorEncrypter decodes and returns the ErrorEncrypter for this hop, // ExtractErrorEncrypter decodes and returns the ErrorEncrypter for this hop,
// along with a failure code to signal if the decoding was successful. The // along with a failure code to signal if the decoding was successful. The
// ErrorEncrypter is used to encrypt errors back to the sender in the event that // ErrorEncrypter is used to encrypt errors back to the sender in the event that