When handling blinded errors, we need to know whether there was a
blinding key in our payload when we successfully parsed our payload
but then found an invalid set of fields. The combination of
parsing and validation in NewPayloadFromReader means that we don't know
whether a blinding point was available to us by the time the error is
returned.
This commit splits parsing and validation into two functions so that
we can take a look at what we actually pulled of the payload in between
parsing and TLV validation.
This commit moves all our validation related to the presence of fields
into ValidateParsedPayloadTypes so that we can handle them in a single
place. We draw the distinction between:
- Validation of the payload (and the context within it's being parsed,
final hop / blinded hop etc)
- Processing and validation of encrypted data, where we perform
additional cryptographic operations and validate that the fields
contained in the blob are valid.
This helps draw the line more clearly between the two validation types,
rather than splitting some payload-releated blinded hop processing
into the encrypted data processing part. The downside of this approach
(vs doing the blinded path payload check _after_ payload validation)
is that we have to pass additional context into payload validation
(ie, whether we got a blinding point in our UpdateAddHtlc - as we
already do for isFinalHop).
To separate blinded route parsing from payload parsing, we need to
return the parsed types map so that we can properly validate blinded
data payloads against what we saw in the onion.
Previously, we'd use the value of nextChanID to infer whether a payload
was for the final hop in a route. This commit updates our packing logic
to explicitly signal to account for blinded routes, which allow zero
value nextChanID in intermediate hops. This is a preparatory commit
that allows us to more thoroughly validate payloads.
Previously, we were using nextChanID to determine whether a hop
payload is for the final recipient. This is no longer suitable in a
route-blinding world where intermediate hops are allowed to have zero
nextChanID TLVs (as this information is provided to forwarding nodes
in their encrypted data). This commit updates payload reading to use
the signal provided by sphinx that we are on the last packet, rather
than implying it from the contents of a hop.
hop.Payload and route.Hop are analogs, with onion payloads encoded from
route.Hops and decoded to hop.Payloads. For checking equality of
encoding/decoding, we implement a helper function to convert
hop.Payloads into route.Hops.