hop

package
v0.17.5-beta Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 19, 2024 License: MIT Imports: 11 Imported by: 0

Documentation

Index

Constants

View Source
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
)

Variables

View Source
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

func NewCustomRecords(parsedTypes tlv.TypeMap) record.CustomSet

NewCustomRecords filters the types parsed from the tlv stream for custom records.

func UseLogger

func UseLogger(logger btclog.Logger)

UseLogger uses a specified Logger to output package logging info. This function is called from the parent package htlcswitch logger initialization.

func ValidateParsedPayloadTypes

func ValidateParsedPayloadTypes(parsedTypes tlv.TypeMap,
	nextHop lnwire.ShortChannelID) error

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.

Types

type DecodeHopIteratorRequest

type DecodeHopIteratorRequest struct {
	OnionReader  io.Reader
	RHash        []byte
	IncomingCltv uint32
}

DecodeHopIteratorRequest encapsulates all date necessary to process an onion packet, perform sphinx replay detection, and schedule the entry for garbage collection.

type DecodeHopIteratorResponse

type DecodeHopIteratorResponse struct {
	HopIterator Iterator
	FailCode    lnwire.FailCode
}

DecodeHopIteratorResponse encapsulates the outcome of a batched sphinx onion processing.

func (*DecodeHopIteratorResponse) Result

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.

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 {
	// Network is the target blockchain network that the HTLC will travel
	// over next.
	Network Network

	// 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
}

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 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.
	HopPayload() (*Payload, 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(ErrorEncrypterExtracter) (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 Network

type Network uint8

Network indicates the blockchain network that is intended to be the next hop for a forwarded HTLC. The existence of this field within the ForwardingInfo struct enables the ability for HTLC to cross chain-boundaries at will.

const (
	// BitcoinNetwork denotes that an HTLC is to be forwarded along the
	// Bitcoin link with the specified short channel ID.
	BitcoinNetwork Network = iota

	// LitecoinNetwork denotes that an HTLC is to be forwarded along the
	// Litecoin link with the specified short channel ID.
	LitecoinNetwork
)

func (Network) String

func (c Network) String() string

String returns the string representation of the target Network.

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) DecodeHopIterator

func (p *OnionProcessor) DecodeHopIterator(r io.Reader, rHash []byte,
	incomingCltv uint32) (Iterator, lnwire.FailCode)

DecodeHopIterator 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) 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) (
	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

func NewLegacyPayload(f *sphinx.HopData) *Payload

NewLegacyPayload builds a Payload from the amount, cltv, and next hop parameters provided by leegacy onion payloads.

func NewPayloadFromReader

func NewPayloadFromReader(r io.Reader) (*Payload, error)

NewPayloadFromReader builds a new Hop from the passed io.Reader. The reader should correspond to the bytes encapsulated in a TLV onion payload.

func (*Payload) AMPRecord

func (h *Payload) AMPRecord() *record.AMP

AMPRecord returns the record corresponding with option_amp parsed from the onion payload.

func (*Payload) CustomRecords

func (h *Payload) CustomRecords() record.CustomSet

CustomRecords returns the custom tlv type records that were parsed from the 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

func (h *Payload) Metadata() []byte

Metadata returns the additional data that is sent along with the payment to the payee.

func (*Payload) MultiPath

func (h *Payload) MultiPath() *record.MPP

MultiPath returns the record corresponding the option_mpp parsed from the onion payload.

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
)

func (PayloadViolation) String

func (v PayloadViolation) String() string

String returns a human-readable description of the violation as a verb.

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:

  1. Decode: to deserialize the ephemeral public key.
  2. 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

Type returns the identifier for a sphinx error encrypter.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL