Documentation ¶
Index ¶
- Constants
- Variables
- func NewCustomRecords(parsedTypes tlv.TypeMap) record.CustomSet
- func UseLogger(logger btclog.Logger)
- func ValidateBlindedRouteData(blindedData *record.BlindedRouteData, incomingAmount lnwire.MilliSatoshi, ...) error
- func ValidateParsedPayloadTypes(parsedTypes tlv.TypeMap, isFinalHop, updateAddBlinding bool) error
- func ValidatePayloadWithBlinded(isFinalHop bool, payloadParsed map[tlv.Type][]byte) error
- func ValidateTLVPayload(parsedTypes map[tlv.Type][]byte, finalHop bool, updateAddBlinding bool) error
- type BlindingKit
- type BlindingProcessor
- type DecodeHopIteratorRequest
- type DecodeHopIteratorResponse
- type EncrypterType
- type ErrInvalidPayload
- type ErrorEncrypter
- type ErrorEncrypterExtracter
- type ForwardingInfo
- type IntroductionErrorEncrypter
- type Iterator
- type OnionProcessor
- func (p *OnionProcessor) DecodeHopIterators(id []byte, reqs []DecodeHopIteratorRequest) ([]DecodeHopIteratorResponse, error)
- func (p *OnionProcessor) ExtractErrorEncrypter(ephemeralKey *btcec.PublicKey) (ErrorEncrypter, lnwire.FailCode)
- func (p *OnionProcessor) ReconstructHopIterator(r io.Reader, rHash []byte, blindingInfo ReconstructBlindingInfo) (Iterator, error)
- func (p *OnionProcessor) Start() error
- func (p *OnionProcessor) Stop() error
- type Payload
- func (h *Payload) AMPRecord() *record.AMP
- func (h *Payload) BlindingPoint() *btcec.PublicKey
- func (h *Payload) CustomRecords() record.CustomSet
- func (h *Payload) EncryptedData() []byte
- func (h *Payload) ForwardingInfo() ForwardingInfo
- func (h *Payload) Metadata() []byte
- func (h *Payload) MultiPath() *record.MPP
- func (h *Payload) TotalAmtMsat() lnwire.MilliSatoshi
- type PayloadViolation
- type ReconstructBlindingInfo
- type RelayingErrorEncrypter
- type RouteRole
- type SphinxErrorEncrypter
- func (s *SphinxErrorEncrypter) Decode(r io.Reader) error
- func (s *SphinxErrorEncrypter) Encode(w io.Writer) error
- func (s *SphinxErrorEncrypter) EncryptFirstHop(failure lnwire.FailureMessage) (lnwire.OpaqueReason, error)
- func (s *SphinxErrorEncrypter) EncryptMalformedError(reason lnwire.OpaqueReason) lnwire.OpaqueReason
- func (s *SphinxErrorEncrypter) IntermediateEncrypt(reason lnwire.OpaqueReason) lnwire.OpaqueReason
- func (s *SphinxErrorEncrypter) Reextract(extract ErrorEncrypterExtracter) error
- func (s *SphinxErrorEncrypter) Type() EncrypterType
Constants ¶
const ( // EncrypterTypeNone signals that no error encyrpter is present, this // can happen if the htlc is originates in the switch. EncrypterTypeNone EncrypterType = 0 // EncrypterTypeSphinx is used to identify a sphinx onion error // encrypter instance. EncrypterTypeSphinx = 1 // EncrypterTypeMock is used to identify a mock obfuscator instance. EncrypterTypeMock = 2 // EncrypterTypeIntroduction is used to identify a sphinx onion error // encrypter where we are the introduction node in a blinded route. It // has the same functionality as EncrypterTypeSphinx, but is used to // mark our special-case error handling. EncrypterTypeIntroduction = 3 // EncrypterTypeRelaying is used to identify a sphinx onion error // encryper where we are a relaying node in a blinded route. It has // the same functionality as a EncrypterTypeSphinx, but is used to mark // our special-case error handling. EncrypterTypeRelaying = 4 )
Variables ¶
var ( // ErrDecodeFailed is returned when we can't decode blinded data. ErrDecodeFailed = errors.New("could not decode blinded data") // ErrNoBlindingPoint is returned when we have not provided a blinding // point for a validated payload with encrypted data set. ErrNoBlindingPoint = errors.New("no blinding point set for validated " + "blinded hop") )
var ( // Exit is a special "hop" denoting that an incoming HTLC is meant to // pay finally to the receiving node. Exit lnwire.ShortChannelID // Source is a sentinel "hop" denoting that an incoming HTLC is // initiated by our own switch. Source lnwire.ShortChannelID )
Functions ¶
func NewCustomRecords ¶
NewCustomRecords filters the types parsed from the tlv stream for custom records.
func UseLogger ¶
UseLogger uses a specified Logger to output package logging info. This function is called from the parent package htlcswitch logger initialization.
func ValidateBlindedRouteData ¶
func ValidateBlindedRouteData(blindedData *record.BlindedRouteData, incomingAmount lnwire.MilliSatoshi, incomingTimelock uint32) error
ValidateBlindedRouteData performs the additional validation that is required for payments that rely on data provided in an encrypted blob to be forwarded. We enforce the blinded route's maximum expiry height so that the route "expires" and a malicious party does not have endless opportunity to probe the blinded route and compare it to updated channel policies in the network.
Note that this function only validates blinded route data for forwarding nodes, as LND does not yet support receiving via a blinded route (which has different validation rules).
func ValidateParsedPayloadTypes ¶
ValidateParsedPayloadTypes checks the types parsed from a hop payload to ensure that the proper fields are either included or omitted. The finalHop boolean should be true if the payload was parsed for an exit hop. The requirements for this method are described in BOLT 04.
func ValidatePayloadWithBlinded ¶
ValidatePayloadWithBlinded validates a payload against the contents of its encrypted data blob.
Types ¶
type BlindingKit ¶
type BlindingKit struct { // Processor provides the low-level cryptographic operations to // handle an encrypted blob of data in a blinded forward. Processor BlindingProcessor // UpdateAddBlinding holds a blinding point that was passed to the // node via update_add_htlc's TLVs. UpdateAddBlinding lnwire.BlindingPointRecord // IncomingCltv is the expiry of the incoming HTLC. IncomingCltv uint32 // IncomingAmount is the amount of the incoming HTLC. IncomingAmount lnwire.MilliSatoshi }
BlindingKit contains the components required to extract forwarding information for hops in a blinded route.
func (*BlindingKit) DecryptAndValidateFwdInfo ¶
func (b *BlindingKit) DecryptAndValidateFwdInfo(payload *Payload, isFinalHop bool, payloadParsed map[tlv.Type][]byte) ( *ForwardingInfo, error)
DecryptAndValidateFwdInfo performs all operations required to decrypt and validate a blinded route.
type BlindingProcessor ¶
type BlindingProcessor interface { // DecryptBlindedHopData decrypts a blinded blob of data using the // ephemeral key provided. DecryptBlindedHopData(ephemPub *btcec.PublicKey, encryptedData []byte) ([]byte, error) // NextEphemeral returns the next hop's ephemeral key, calculated // from the current ephemeral key provided. NextEphemeral(*btcec.PublicKey) (*btcec.PublicKey, error) }
BlindingProcessor is an interface that provides the cryptographic operations required for processing blinded hops.
This interface is extracted to allow more granular testing of blinded forwarding calculations.
type DecodeHopIteratorRequest ¶
type DecodeHopIteratorRequest struct { OnionReader io.Reader RHash []byte IncomingCltv uint32 IncomingAmount lnwire.MilliSatoshi BlindingPoint lnwire.BlindingPointRecord }
DecodeHopIteratorRequest encapsulates all date necessary to process an onion packet, perform sphinx replay detection, and schedule the entry for garbage collection.
type DecodeHopIteratorResponse ¶
DecodeHopIteratorResponse encapsulates the outcome of a batched sphinx onion processing.
func (*DecodeHopIteratorResponse) Result ¶
func (r *DecodeHopIteratorResponse) Result() (Iterator, lnwire.FailCode)
Result returns the (HopIterator, lnwire.FailCode) tuple, which should correspond to the index of a particular DecodeHopIteratorRequest.
NOTE: The HopIterator should be considered invalid if the fail code is anything but lnwire.CodeNone.
type EncrypterType ¶
type EncrypterType byte
EncrypterType establishes an enum used in serialization to indicate how to decode a concrete instance of the ErrorEncrypter interface.
func (EncrypterType) IsBlinded ¶
func (e EncrypterType) IsBlinded() bool
IsBlinded returns a boolean indicating whether the error encrypter belongs to a blinded route.
type ErrInvalidPayload ¶
type ErrInvalidPayload struct { // Type the record's type that cause the violation. Type tlv.Type // Violation is an enum indicating the type of violation detected in // processing Type. Violation PayloadViolation // FinalHop if true, indicates that the violation is for the final hop // in the route (identified by next hop id), otherwise the violation is // for an intermediate hop. FinalHop bool }
ErrInvalidPayload is an error returned when a parsed onion payload either included or omitted incorrect records for a particular hop type.
func (ErrInvalidPayload) Error ¶
func (e ErrInvalidPayload) Error() string
Error returns a human-readable description of the invalid payload error.
type ErrorEncrypter ¶
type ErrorEncrypter interface { // EncryptFirstHop transforms a concrete failure message into an // encrypted opaque failure reason. This method will be used at the // source that the error occurs. It differs from IntermediateEncrypt // slightly, in that it computes a proper MAC over the error. EncryptFirstHop(lnwire.FailureMessage) (lnwire.OpaqueReason, error) // EncryptMalformedError is similar to EncryptFirstHop (it adds the // MAC), but it accepts an opaque failure reason rather than a failure // message. This method is used when we receive an // UpdateFailMalformedHTLC from the remote peer and then need to // convert that into a proper error from only the raw bytes. EncryptMalformedError(lnwire.OpaqueReason) lnwire.OpaqueReason // IntermediateEncrypt wraps an already encrypted opaque reason error // in an additional layer of onion encryption. This process repeats // until the error arrives at the source of the payment. IntermediateEncrypt(lnwire.OpaqueReason) lnwire.OpaqueReason // Type returns an enum indicating the underlying concrete instance // backing this interface. Type() EncrypterType // Encode serializes the encrypter's ephemeral public key to the given // io.Writer. Encode(io.Writer) error // Decode deserializes the encrypter' ephemeral public key from the // given io.Reader. Decode(io.Reader) error // Reextract rederives the encrypter using the extracter, performing an // ECDH with the sphinx router's key and the ephemeral public key. // // NOTE: This should be called shortly after Decode to properly // reinitialize the error encrypter. Reextract(ErrorEncrypterExtracter) error }
ErrorEncrypter is an interface that is used to encrypt HTLC related errors at the source of the error, and also at each intermediate hop all the way back to the source of the payment.
type ErrorEncrypterExtracter ¶
type ErrorEncrypterExtracter func(*btcec.PublicKey) (ErrorEncrypter, lnwire.FailCode)
ErrorEncrypterExtracter defines a function signature that extracts an ErrorEncrypter from an sphinx OnionPacket.
type ForwardingInfo ¶
type ForwardingInfo struct { // NextHop is the channel ID of the next hop. The received HTLC should // be forwarded to this particular channel in order to continue the // end-to-end route. NextHop lnwire.ShortChannelID // AmountToForward is the amount of milli-satoshis that the receiving // node should forward to the next hop. AmountToForward lnwire.MilliSatoshi // OutgoingCTLV is the specified value of the CTLV timelock to be used // in the outgoing HTLC. OutgoingCTLV uint32 // NextBlinding is an optional blinding point to be passed to the next // node in UpdateAddHtlc. This field is set if the htlc is part of a // blinded route. NextBlinding lnwire.BlindingPointRecord }
ForwardingInfo contains all the information that is necessary to forward and incoming HTLC to the next hop encoded within a valid HopIterator instance. Forwarding links are to use this information to authenticate the information received within the incoming HTLC, to ensure that the prior hop didn't tamper with the end-to-end routing information at all.
type IntroductionErrorEncrypter ¶
type IntroductionErrorEncrypter struct { // ErrorEncrypter is the underlying error encrypter, embedded // directly in the struct so that we don't have to re-implement the // ErrorEncrypter interface. ErrorEncrypter }
IntroductionErrorEncrypter is a wrapper type on SphinxErrorEncrypter which is used to signal that we have special HTLC error handling for this hop.
func NewIntroductionErrorEncrypter ¶
func NewIntroductionErrorEncrypter() *IntroductionErrorEncrypter
NewIntroductionErrorEncrypter returns a blank IntroductionErrorEncrypter.
func (*IntroductionErrorEncrypter) Reextract ¶
func (i *IntroductionErrorEncrypter) Reextract( extract ErrorEncrypterExtracter) error
Reextract rederives the error encrypter from the currently held EphemeralKey, relying on the logic in the underlying SphinxErrorEncrypter.
func (*IntroductionErrorEncrypter) Type ¶
func (i *IntroductionErrorEncrypter) Type() EncrypterType
Type returns the identifier for an introduction error encrypter.
type Iterator ¶
type Iterator interface { // HopPayload returns the set of fields that detail exactly _how_ this // hop should forward the HTLC to the next hop. Additionally, the // information encoded within the returned ForwardingInfo is to be used // by each hop to authenticate the information given to it by the prior // hop. The payload will also contain any additional TLV fields provided // by the sender. The role that this hop plays in the context of // route blinding (regular, introduction or relaying) is returned // whenever the payload is successfully parsed, even if we subsequently // face a validation error. HopPayload() (*Payload, RouteRole, error) // EncodeNextHop encodes the onion packet destined for the next hop // into the passed io.Writer. EncodeNextHop(w io.Writer) error // ExtractErrorEncrypter returns the ErrorEncrypter needed for this hop, // along with a failure code to signal if the decoding was successful. ExtractErrorEncrypter(extractor ErrorEncrypterExtracter, introductionNode bool) (ErrorEncrypter, lnwire.FailCode) }
Iterator is an interface that abstracts away the routing information included in HTLC's which includes the entirety of the payment path of an HTLC. This interface provides two basic method which carry out: how to interpret the forwarding information encoded within the HTLC packet, and hop to encode the forwarding information for the _next_ hop.
type OnionProcessor ¶
type OnionProcessor struct {
// contains filtered or unexported fields
}
OnionProcessor is responsible for keeping all sphinx dependent parts inside and expose only decoding function. With such approach we give freedom for subsystems which wants to decode sphinx path to not be dependable from sphinx at all.
NOTE: The reason for keeping decoder separated from hop iterator is too maintain the hop iterator abstraction. Without it the structures which using the hop iterator should contain sphinx router which makes their creations in tests dependent from the sphinx internal parts.
func NewOnionProcessor ¶
func NewOnionProcessor(router *sphinx.Router) *OnionProcessor
NewOnionProcessor creates new instance of decoder.
func (*OnionProcessor) DecodeHopIterators ¶
func (p *OnionProcessor) DecodeHopIterators(id []byte, reqs []DecodeHopIteratorRequest) ([]DecodeHopIteratorResponse, error)
DecodeHopIterators performs batched decoding and validation of incoming sphinx packets. For the same `id`, this method will return the same iterators and failcodes upon subsequent invocations.
NOTE: In order for the responses to be valid, the caller must guarantee that the presented readers and rhashes *NEVER* deviate across invocations for the same id.
func (*OnionProcessor) ExtractErrorEncrypter ¶
func (p *OnionProcessor) ExtractErrorEncrypter(ephemeralKey *btcec.PublicKey) ( ErrorEncrypter, lnwire.FailCode)
ExtractErrorEncrypter takes an io.Reader which should contain the onion packet as original received by a forwarding node and creates an ErrorEncrypter instance using the derived shared secret. In the case that en error occurs, a lnwire failure code detailing the parsing failure will be returned.
func (*OnionProcessor) ReconstructHopIterator ¶
func (p *OnionProcessor) ReconstructHopIterator(r io.Reader, rHash []byte, blindingInfo ReconstructBlindingInfo) (Iterator, error)
ReconstructHopIterator attempts to decode a valid sphinx packet from the passed io.Reader instance using the rHash as the associated data when checking the relevant MACs during the decoding process.
func (*OnionProcessor) Start ¶
func (p *OnionProcessor) Start() error
Start spins up the onion processor's sphinx router.
func (*OnionProcessor) Stop ¶
func (p *OnionProcessor) Stop() error
Stop shutsdown the onion processor's sphinx router.
type Payload ¶
type Payload struct { // FwdInfo holds the basic parameters required for HTLC forwarding, e.g. // amount, cltv, and next hop. FwdInfo ForwardingInfo // MPP holds the info provided in an option_mpp record when parsed from // a TLV onion payload. MPP *record.MPP // AMP holds the info provided in an option_amp record when parsed from // a TLV onion payload. AMP *record.AMP // contains filtered or unexported fields }
Payload encapsulates all information delivered to a hop in an onion payload. A Hop can represent either a TLV or legacy payload. The primary forwarding instruction can be accessed via ForwardingInfo, and additional records can be accessed by other member functions.
func NewLegacyPayload ¶
NewLegacyPayload builds a Payload from the amount, cltv, and next hop parameters provided by leegacy onion payloads.
func ParseTLVPayload ¶
ParseTLVPayload builds a new Hop from the passed io.Reader and returns a map of all the types that were found in the payload. This function does not perform validation of TLV types included in the payload.
func (*Payload) AMPRecord ¶
AMPRecord returns the record corresponding with option_amp parsed from the onion payload.
func (*Payload) BlindingPoint ¶
func (h *Payload) BlindingPoint() *btcec.PublicKey
BlindingPoint returns the route blinding point parsed from the onion payload.
func (*Payload) CustomRecords ¶
CustomRecords returns the custom tlv type records that were parsed from the payload.
func (*Payload) EncryptedData ¶
EncryptedData returns the route blinding encrypted data parsed from the onion payload.
func (*Payload) ForwardingInfo ¶
func (h *Payload) ForwardingInfo() ForwardingInfo
ForwardingInfo returns the basic parameters required for HTLC forwarding, e.g. amount, cltv, and next hop.
func (*Payload) Metadata ¶
Metadata returns the additional data that is sent along with the payment to the payee.
func (*Payload) MultiPath ¶
MultiPath returns the record corresponding the option_mpp parsed from the onion payload.
func (*Payload) TotalAmtMsat ¶
func (h *Payload) TotalAmtMsat() lnwire.MilliSatoshi
TotalAmtMsat returns the total amount sent to the final hop, as set by the payee.
type PayloadViolation ¶
type PayloadViolation byte
PayloadViolation is an enum encapsulating the possible invalid payload violations that can occur when processing or validating a payload.
const ( // OmittedViolation indicates that a type was expected to be found the // payload but was absent. OmittedViolation PayloadViolation = iota // IncludedViolation indicates that a type was expected to be omitted // from the payload but was present. IncludedViolation // RequiredViolation indicates that an unknown even type was found in // the payload that we could not process. RequiredViolation // InsufficientViolation indicates that the provided type does // not satisfy constraints. InsufficientViolation )
func (PayloadViolation) String ¶
func (v PayloadViolation) String() string
String returns a human-readable description of the violation as a verb.
type ReconstructBlindingInfo ¶
type ReconstructBlindingInfo struct { // BlindingKey is the blinding point set in UpdateAddHTLC. BlindingKey lnwire.BlindingPointRecord // IncomingAmt is the amount for the incoming HTLC. IncomingAmt lnwire.MilliSatoshi // IncomingExpiry is the expiry height of the incoming HTLC. IncomingExpiry uint32 }
ReconstructBlindingInfo contains the information required to reconstruct a blinded onion.
type RelayingErrorEncrypter ¶
type RelayingErrorEncrypter struct {
ErrorEncrypter
}
RelayingErrorEncrypter is a wrapper type on SphinxErrorEncrypter which is used to signal that we have special HTLC error handling for this hop.
func NewRelayingErrorEncrypter ¶
func NewRelayingErrorEncrypter() *RelayingErrorEncrypter
NewRelayingErrorEncrypter returns a blank RelayingErrorEncrypter with an underlying SphinxErrorEncrypter.
func (*RelayingErrorEncrypter) Reextract ¶
func (r *RelayingErrorEncrypter) Reextract( extract ErrorEncrypterExtracter) error
Reextract rederives the error encrypter from the currently held EphemeralKey, relying on the logic in the underlying SphinxErrorEncrypter.
func (*RelayingErrorEncrypter) Type ¶
func (r *RelayingErrorEncrypter) Type() EncrypterType
Type returns the identifier for a relaying error encrypter.
type RouteRole ¶
type RouteRole uint8
RouteRole represents the different types of roles a node can have as a recipient of a HTLC.
const ( // RouteRoleCleartext represents a regular route hop. RouteRoleCleartext RouteRole = iota // RouteRoleIntroduction represents an introduction node in a blinded // path, characterized by a blinding point in the onion payload. RouteRoleIntroduction // RouteRoleRelaying represents a relaying node in a blinded path, // characterized by a blinding point in update_add_htlc. RouteRoleRelaying )
func NewRouteRole ¶
NewRouteRole returns the role we're playing in a route depending on the blinding points set (or not). If we are in the situation where we received blinding points in both the update add message and the payload:
- We must have had a valid update add blinding point, because we were able to decrypt our onion to get the payload blinding point.
- We return a relaying node role, because an introduction node (by definition) does not receive a blinding point in update add.
- We assume the sending node to be buggy (including a payload blinding where it shouldn't), and rely on validation elsewhere to handle this.
type SphinxErrorEncrypter ¶
type SphinxErrorEncrypter struct { *sphinx.OnionErrorEncrypter EphemeralKey *btcec.PublicKey }
SphinxErrorEncrypter is a concrete implementation of both the ErrorEncrypter interface backed by an implementation of the Sphinx packet format. As a result, all errors handled are themselves wrapped in layers of onion encryption and must be treated as such accordingly.
func NewSphinxErrorEncrypter ¶
func NewSphinxErrorEncrypter() *SphinxErrorEncrypter
NewSphinxErrorEncrypter initializes a blank sphinx error encrypter, that should be used to deserialize an encoded SphinxErrorEncrypter. Since the actual encrypter is not stored in plaintext while at rest, reconstructing the error encrypter requires:
- Decode: to deserialize the ephemeral public key.
- Reextract: to "unlock" the actual error encrypter using an active OnionProcessor.
func (*SphinxErrorEncrypter) Decode ¶
func (s *SphinxErrorEncrypter) Decode(r io.Reader) error
Decode reconstructs the error encrypter's ephemeral public key from the provided io.Reader.
func (*SphinxErrorEncrypter) Encode ¶
func (s *SphinxErrorEncrypter) Encode(w io.Writer) error
Encode serializes the error encrypter' ephemeral public key to the provided io.Writer.
func (*SphinxErrorEncrypter) EncryptFirstHop ¶
func (s *SphinxErrorEncrypter) EncryptFirstHop( failure lnwire.FailureMessage) (lnwire.OpaqueReason, error)
EncryptFirstHop transforms a concrete failure message into an encrypted opaque failure reason. This method will be used at the source that the error occurs. It differs from BackwardObfuscate slightly, in that it computes a proper MAC over the error.
NOTE: Part of the ErrorEncrypter interface.
func (*SphinxErrorEncrypter) EncryptMalformedError ¶
func (s *SphinxErrorEncrypter) EncryptMalformedError( reason lnwire.OpaqueReason) lnwire.OpaqueReason
EncryptMalformedError is similar to EncryptFirstHop (it adds the MAC), but it accepts an opaque failure reason rather than a failure message. This method is used when we receive an UpdateFailMalformedHTLC from the remote peer and then need to convert that into an proper error from only the raw bytes.
NOTE: Part of the ErrorEncrypter interface.
func (*SphinxErrorEncrypter) IntermediateEncrypt ¶
func (s *SphinxErrorEncrypter) IntermediateEncrypt( reason lnwire.OpaqueReason) lnwire.OpaqueReason
IntermediateEncrypt wraps an already encrypted opaque reason error in an additional layer of onion encryption. This process repeats until the error arrives at the source of the payment. We re-encrypt the message on the backwards path to ensure that the error is indistinguishable from any other error seen.
NOTE: Part of the ErrorEncrypter interface.
func (*SphinxErrorEncrypter) Reextract ¶
func (s *SphinxErrorEncrypter) Reextract( extract ErrorEncrypterExtracter) error
Reextract rederives the error encrypter from the currently held EphemeralKey. This intended to be used shortly after Decode, to fully initialize a SphinxErrorEncrypter.
func (*SphinxErrorEncrypter) Type ¶
func (s *SphinxErrorEncrypter) Type() EncrypterType
Type returns the identifier for a sphinx error encrypter.