Documentation ¶
Index ¶
- Constants
- Variables
- func DisableLog()
- func ExpectedFee(f ForwardingPolicy, htlcAmt lnwire.MilliSatoshi) lnwire.MilliSatoshi
- func UseLogger(logger btclog.Logger)
- type BatchTicker
- type ChanClose
- type ChannelCloseType
- type ChannelLink
- type ChannelLinkConfig
- type CircuitFwdActions
- type CircuitKey
- type CircuitMap
- type CircuitMapConfig
- type CircuitModifier
- type Config
- type DecodeHopIteratorRequest
- type DecodeHopIteratorResponse
- type EncrypterType
- type ErrorDecrypter
- type ErrorEncrypter
- type ErrorEncrypterExtracter
- type ForwardingError
- type ForwardingInfo
- type ForwardingLog
- type ForwardingPolicy
- type HopIterator
- type InvoiceDatabase
- type Keystone
- type MailBox
- type NetworkHop
- type OnionProcessor
- func (p *OnionProcessor) DecodeHopIterator(r io.Reader, rHash []byte, incomingCltv uint32) (HopIterator, lnwire.FailCode)
- func (p *OnionProcessor) DecodeHopIterators(id []byte, reqs []DecodeHopIteratorRequest) ([]DecodeHopIteratorResponse, error)
- func (p *OnionProcessor) ExtractErrorEncrypter(ephemeralKey *btcec.PublicKey) (ErrorEncrypter, lnwire.FailCode)
- func (p *OnionProcessor) Start() error
- func (p *OnionProcessor) Stop() error
- type PaymentCircuit
- type Peer
- type Sequencer
- type SphinxErrorDecrypter
- 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) IntermediateEncrypt(reason lnwire.OpaqueReason) lnwire.OpaqueReason
- func (s *SphinxErrorEncrypter) Reextract(extract ErrorEncrypterExtracter) error
- func (s *SphinxErrorEncrypter) Type() EncrypterType
- type Switch
- func (s *Switch) AddLink(link ChannelLink) error
- func (s *Switch) CircuitModifier() CircuitModifier
- func (s *Switch) CloseLink(chanPoint *wire.OutPoint, closeType ChannelCloseType, ...) (chan *lnrpc.CloseStatusUpdate, chan error)
- func (s *Switch) FlushForwardingEvents() error
- func (s *Switch) ForwardPackets(packets ...*htlcPacket) chan error
- func (s *Switch) GetLink(chanID lnwire.ChannelID) (ChannelLink, error)
- func (s *Switch) GetLinksByInterface(hop [33]byte) ([]ChannelLink, error)
- func (s *Switch) ProcessContractResolution(msg contractcourt.ResolutionMsg) error
- func (s *Switch) RemoveLink(chanID lnwire.ChannelID) error
- func (s *Switch) SendHTLC(nextNode [33]byte, htlc *lnwire.UpdateAddHTLC, deobfuscator ErrorDecrypter) ([sha256.Size]byte, error)
- func (s *Switch) Start() error
- func (s *Switch) Stop() error
- func (s *Switch) UpdateForwardingPolicies(newPolicy ForwardingPolicy, targetChans ...wire.OutPoint) error
- func (s *Switch) UpdateShortChanID(chanID lnwire.ChannelID, shortChanID lnwire.ShortChannelID) error
- type Ticker
- type UnknownEncrypterType
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 )
Variables ¶
var ( // ErrCorruptedCircuitMap indicates that the on-disk bucketing structure // has altered since the circuit map instance was initialized. ErrCorruptedCircuitMap = errors.New("circuit map has been corrupted") // ErrCircuitNotInHashIndex indicates that a particular circuit did not // appear in the in-memory hash index. ErrCircuitNotInHashIndex = errors.New("payment circuit not found in " + "hash index") // ErrUnknownCircuit signals that circuit could not be removed from the // map because it was not found. ErrUnknownCircuit = errors.New("unknown payment circuit") // ErrCircuitClosing signals that an htlc has already closed this // circuit in-memory. ErrCircuitClosing = errors.New("circuit has already been closed") // ErrDuplicateCircuit signals that this circuit was previously // added. ErrDuplicateCircuit = errors.New("duplicate circuit add") // ErrUnknownKeystone signals that no circuit was found using the // outgoing circuit key. ErrUnknownKeystone = errors.New("unknown circuit keystone") // ErrDuplicateKeystone signals that this circuit was previously // assigned a keystone. ErrDuplicateKeystone = errors.New("cannot add duplicate keystone") )
var ( // ErrChannelLinkNotFound is used when channel link hasn't been found. ErrChannelLinkNotFound = errors.New("channel link not found") // ErrDuplicateAdd signals that the ADD htlc was already forwarded // through the switch and is locked into another commitment txn. ErrDuplicateAdd = errors.New("duplicate add HTLC detected") // ErrIncompleteForward is used when an htlc was already forwarded // through the switch, but did not get locked into another commitment // txn. ErrIncompleteForward = errors.Errorf("incomplete forward detected") )
var ErrInternalLinkFailure = errors.New("internal link failure")
ErrInternalLinkFailure is a generic error returned to the remote party so as to obfuscate the true failure.
var ErrMailBoxShuttingDown = errors.New("mailbox is shutting down")
ErrMailBoxShuttingDown is returned when the mailbox is interrupted by a shutdown request.
var ( // ErrSequencerCorrupted signals that the persistence engine was not // initialized, or has been corrupted since startup. ErrSequencerCorrupted = errors.New( "sequencer database has been corrupted") )
Functions ¶
func DisableLog ¶
func DisableLog()
DisableLog disables all library log output. Logging output is disabled by default until UseLogger is called.
func ExpectedFee ¶
func ExpectedFee(f ForwardingPolicy, htlcAmt lnwire.MilliSatoshi) lnwire.MilliSatoshi
ExpectedFee computes the expected fee for a given htlc amount. The value returned from this function is to be used as a sanity check when forwarding HTLC's to ensure that an incoming HTLC properly adheres to our propagated forwarding policy.
TODO(roasbeef): also add in current available channel bandwidth, inverse func
Types ¶
type BatchTicker ¶
type BatchTicker struct {
// contains filtered or unexported fields
}
BatchTicker implements the Ticker interface, and wraps a time.Ticker.
func NewBatchTicker ¶
func NewBatchTicker(t *time.Ticker) *BatchTicker
NewBatchTicker returns a new BatchTicker that wraps the passed time.Ticker.
func (*BatchTicker) Start ¶
func (t *BatchTicker) Start() <-chan time.Time
Start returns the tick channel for the underlying time.Ticker.
type ChanClose ¶
type ChanClose struct { // CloseType is a variable which signals the type of channel closure the // peer should execute. CloseType ChannelCloseType // ChanPoint represent the id of the channel which should be closed. ChanPoint *wire.OutPoint // TargetFeePerKw is the ideal fee that was specified by the caller. // This value is only utilized if the closure type is CloseRegular. // This will be the starting offered fee when the fee negotiation // process for the cooperative closure transaction kicks off. TargetFeePerKw lnwallet.SatPerKWeight // Updates is used by request creator to receive the notifications about // execution of the close channel request. Updates chan *lnrpc.CloseStatusUpdate // Err is used by request creator to receive request execution error. Err chan error }
ChanClose represents a request which close a particular channel specified by its id.
type ChannelCloseType ¶
type ChannelCloseType uint8
ChannelCloseType is a enum which signals the type of channel closure the peer should execute.
const ( // CloseRegular indicates a regular cooperative channel closure // should be attempted. CloseRegular ChannelCloseType = iota // CloseBreach indicates that a channel breach has been detected, and // the link should immediately be marked as unavailable. CloseBreach )
type ChannelLink ¶
type ChannelLink interface { // HandleSwitchPacket handles the switch packets. This packets might be // forwarded to us from another channel link in case the htlc update // came from another peer or if the update was created by user // initially. // // NOTE: This function MUST be non-blocking (or block as little as // possible). HandleSwitchPacket(*htlcPacket) error // HandleChannelUpdate handles the htlc requests as settle/add/fail // which sent to us from remote peer we have a channel with. // // NOTE: This function MUST be non-blocking (or block as little as // possible). HandleChannelUpdate(lnwire.Message) // ChanID returns the channel ID for the channel link. The channel ID // is a more compact representation of a channel's full outpoint. ChanID() lnwire.ChannelID // ShortChanID returns the short channel ID for the channel link. The // short channel ID encodes the exact location in the main chain that // the original funding output can be found. ShortChanID() lnwire.ShortChannelID // UpdateShortChanID updates the short channel ID for a link. This may // be required in the event that a link is created before the short // chan ID for it is known, or a re-org occurs, and the funding // transaction changes location within the chain. UpdateShortChanID(lnwire.ShortChannelID) // UpdateForwardingPolicy updates the forwarding policy for the target // ChannelLink. Once updated, the link will use the new forwarding // policy to govern if it an incoming HTLC should be forwarded or not. UpdateForwardingPolicy(ForwardingPolicy) // Bandwidth returns the amount of milli-satoshis which current link // might pass through channel link. The value returned from this method // represents the up to date available flow through the channel. This // takes into account any forwarded but un-cleared HTLC's, and any // HTLC's which have been set to the over flow queue. Bandwidth() lnwire.MilliSatoshi // Stats return the statistics of channel link. Number of updates, // total sent/received milli-satoshis. Stats() (uint64, lnwire.MilliSatoshi, lnwire.MilliSatoshi) // Peer returns the representation of remote peer with which we have // the channel link opened. Peer() Peer // EligibleToForward returns a bool indicating if the channel is able // to actively accept requests to forward HTLC's. A channel may be // active, but not able to forward HTLC's if it hasn't yet finalized // the pre-channel operation protocol with the remote peer. The switch // will use this function in forwarding decisions accordingly. EligibleToForward() bool // AttachMailBox delivers an active MailBox to the link. The MailBox may // have buffered messages. AttachMailBox(MailBox) // Start/Stop are used to initiate the start/stop of the channel link // functioning. Start() error Stop() }
ChannelLink is an interface which represents the subsystem for managing the incoming htlc requests, applying the changes to the channel, and also propagating/forwarding it to htlc switch.
abstraction level ^ | | - - - - - - - - - - - - Lightning - - - - - - - - - - - - - | | (Switch) (Switch) (Switch) | Alice <-- channel link --> Bob <-- channel link --> Carol | | - - - - - - - - - - - - - TCP - - - - - - - - - - - - - - - | | (Peer) (Peer) (Peer) | Alice <----- tcp conn --> Bob <---- tcp conn -----> Carol |
func NewChannelLink ¶
func NewChannelLink(cfg ChannelLinkConfig, channel *lnwallet.LightningChannel, currentHeight uint32) ChannelLink
NewChannelLink creates a new instance of a ChannelLink given a configuration and active channel that will be used to verify/apply updates to.
type ChannelLinkConfig ¶
type ChannelLinkConfig struct { // FwrdingPolicy is the initial forwarding policy to be used when // deciding whether to forwarding incoming HTLC's or not. This value // can be updated with subsequent calls to UpdateForwardingPolicy // targeted at a given ChannelLink concrete interface implementation. FwrdingPolicy ForwardingPolicy // Circuits provides restricted access to the switch's circuit map, // allowing the link to open and close circuits. Circuits CircuitModifier // Switch provides a reference to the HTLC switch, we only use this in // testing to access circuit operations not typically exposed by the // CircuitModifier. // // TODO(conner): remove after refactoring htlcswitch testing framework. Switch *Switch // ForwardPackets attempts to forward the batch of htlcs through the // switch. Any failed packets will be returned to the provided // ChannelLink. ForwardPackets func(...*htlcPacket) chan error // DecodeHopIterators facilitates batched decoding of HTLC Sphinx onion // blobs, which are then used to inform how to forward an HTLC. // // NOTE: This function assumes the same set of readers and preimages // are always presented for the same identifier. DecodeHopIterators func([]byte, []DecodeHopIteratorRequest) ( []DecodeHopIteratorResponse, error) // ExtractErrorEncrypter function is responsible for decoding HTLC // Sphinx onion blob, and creating onion failure obfuscator. ExtractErrorEncrypter ErrorEncrypterExtracter // GetLastChannelUpdate retrieves the latest routing policy for this // particular channel. This will be used to provide payment senders our // latest policy when sending encrypted error messages. GetLastChannelUpdate func() (*lnwire.ChannelUpdate, error) // Peer is a lightning network node with which we have the channel link // opened. Peer Peer // Registry is a sub-system which responsible for managing the invoices // in thread-safe manner. Registry InvoiceDatabase // PreimageCache is a global witness beacon that houses any new // preimages discovered by other links. We'll use this to add new // witnesses that we discover which will notify any sub-systems // subscribed to new events. PreimageCache contractcourt.WitnessBeacon // UpdateContractSignals is a function closure that we'll use to update // outside sub-systems with the latest signals for our inner Lightning // channel. These signals will notify the caller when the channel has // been closed, or when the set of active HTLC's is updated. UpdateContractSignals func(*contractcourt.ContractSignals) error // ChainEvents is an active subscription to the chain watcher for this // channel to be notified of any on-chain activity related to this // channel. ChainEvents *contractcourt.ChainEventSubscription // FeeEstimator is an instance of a live fee estimator which will be // used to dynamically regulate the current fee of the commitment // transaction to ensure timely confirmation. FeeEstimator lnwallet.FeeEstimator // BlockEpochs is an active block epoch event stream backed by an // active ChainNotifier instance. The ChannelLink will use new block // notifications sent over this channel to decide when a _new_ HTLC is // too close to expiry, and also when any active HTLC's have expired // (or are close to expiry). BlockEpochs *chainntnfs.BlockEpochEvent // DebugHTLC should be turned on if you want all HTLCs sent to a node // with the debug htlc R-Hash are immediately settled in the next // available state transition. DebugHTLC bool // HodlHTLC should be active if you want this node to refrain from // settling all incoming HTLCs with the sender if it finds itself to be // the exit node. // // NOTE: HodlHTLC should be active in conjunction with DebugHTLC. HodlHTLC bool // SyncStates is used to indicate that we need send the channel // reestablishment message to the remote peer. It should be done if our // clients have been restarted, or remote peer have been reconnected. SyncStates bool // BatchTicker is the ticker that determines the interval that we'll // use to check the batch to see if there're any updates we should // flush out. By batching updates into a single commit, we attempt to // increase throughput by maximizing the number of updates coalesced // into a single commit. BatchTicker Ticker // FwdPkgGCTicker is the ticker determining the frequency at which // garbage collection of forwarding packages occurs. We use a // time-based approach, as opposed to block epochs, as to not hinder // syncing. FwdPkgGCTicker Ticker // BatchSize is the max size of a batch of updates done to the link // before we do a state update. BatchSize uint32 // UnsafeReplay will cause a link to replay the adds in its latest // commitment txn after the link is restarted. This should only be used // in testing, it is here to ensure the sphinx replay detection on the // receiving node is persistent. UnsafeReplay bool }
ChannelLinkConfig defines the configuration for the channel link. ALL elements within the configuration MUST be non-nil for channel link to carry out its duties.
type CircuitFwdActions ¶
type CircuitFwdActions struct { // Adds is the subsequence of circuits that were successfully committed // in the circuit map. Adds []*PaymentCircuit // Drops is the subsequence of circuits for which no action should be // done. Drops []*PaymentCircuit // Fails is the subsequence of circuits that should be failed back by // the calling link. Fails []*PaymentCircuit }
CircuitFwdActions represents the forwarding decision made by the circuit map, and is returned from CommitCircuits. The sequence of circuits provided to CommitCircuits is split into three sub-sequences, allowing the caller to do an in-order scan, comparing the head of each subsequence, to determine the decision made by the circuit map.
type CircuitKey ¶
type CircuitKey = channeldb.CircuitKey
CircuitKey is a tuple of channel ID and HTLC ID, used to uniquely identify HTLCs in a circuit. Circuits are identified primarily by the circuit key of the incoming HTLC. However, a circuit may also be referenced by its outgoing circuit key after the HTLC has been forwarded via the outgoing link.
var EmptyCircuitKey CircuitKey
EmptyCircuitKey is a default value for an outgoing circuit key returned when a circuit's keystone has not been set. Note that this value is invalid for use as a keystone, since the outgoing channel id can never be equal to sourceHop.
type CircuitMap ¶
type CircuitMap interface { CircuitModifier // CommitCircuits attempts to add the given circuits to the circuit // map. The list of circuits is split into three distinct // sub-sequences, corresponding to adds, drops, and fails. Adds should // be forwarded to the switch, while fails should be failed back // locally within the calling link. CommitCircuits(circuit ...*PaymentCircuit) (*CircuitFwdActions, error) // CloseCircuit marks the circuit identified by `outKey` as closing // in-memory, which prevents duplicate settles/fails from completing an // open circuit twice. CloseCircuit(outKey CircuitKey) (*PaymentCircuit, error) // FailCircuit is used by locally failed HTLCs to mark the circuit // identified by `inKey` as closing in-memory, which prevents duplicate // settles/fails from being accepted for the same circuit. FailCircuit(inKey CircuitKey) (*PaymentCircuit, error) // LookupCircuit queries the circuit map for the circuit identified by // inKey. LookupCircuit(inKey CircuitKey) *PaymentCircuit // LookupOpenCircuit queries the circuit map for a circuit identified // by its outgoing circuit key. LookupOpenCircuit(outKey CircuitKey) *PaymentCircuit // LookupByPaymentHash queries the circuit map and returns all open // circuits that use the given payment hash. LookupByPaymentHash(hash [32]byte) []*PaymentCircuit // NumPending returns the total number of active circuits added by // CommitCircuits. NumPending() int // NumOpen returns the number of circuits with HTLCs that have been // forwarded via an outgoing link. NumOpen() int }
CircuitMap is an interface for managing the construction and teardown of payment circuits used by the switch.
func NewCircuitMap ¶
func NewCircuitMap(cfg *CircuitMapConfig) (CircuitMap, error)
NewCircuitMap creates a new instance of the circuitMap.
type CircuitMapConfig ¶
type CircuitMapConfig struct { // DB provides the persistent storage engine for the circuit map. // TODO(conner): create abstraction to allow for the substitution of // other persistence engines. DB *channeldb.DB // ExtractErrorEncrypter derives the shared secret used to encrypt // errors from the obfuscator's ephemeral public key. ExtractErrorEncrypter ErrorEncrypterExtracter }
CircuitMapConfig houses the critical interfaces and references necessary to parameterize an instance of circuitMap.
type CircuitModifier ¶
type CircuitModifier interface { // OpenCircuits preemptively records a batch keystones that will mark // currently pending circuits as open. These changes can be rolled back // on restart if the outgoing Adds do not make it into a commitment // txn. OpenCircuits(...Keystone) error // TrimOpenCircuits removes a channel's open channels with htlc indexes // above `start`. TrimOpenCircuits(chanID lnwire.ShortChannelID, start uint64) error // DeleteCircuits removes the incoming circuit key to remove all // persistent references to a circuit. Returns a ErrUnknownCircuit if // any of the incoming keys are not known. DeleteCircuits(inKeys ...CircuitKey) error }
CircuitModifier is a common interface used by channel links to modify the contents of the circuit map maintained by the switch.
type Config ¶
type Config struct { // SelfKey is the key of the backing Lightning node. This key is used // to properly craft failure messages, such that the Layer 3 router can // properly route around link./vertex failures. SelfKey *btcec.PublicKey // FwdingLog is an interface that will be used by the switch to log // forwarding events. A forwarding event happens each time a payment // circuit is successfully completed. So when we forward an HTLC, and a // settle is eventually received. FwdingLog ForwardingLog // LocalChannelClose kicks-off the workflow to execute a cooperative or // forced unilateral closure of the channel initiated by a local // subsystem. LocalChannelClose func(pubKey []byte, request *ChanClose) // DB is the channeldb instance that will be used to back the switch's // persistent circuit map. DB *channeldb.DB // SwitchPackager provides access to the forwarding packages of all // active channels. This gives the switch the ability to read arbitrary // forwarding packages, and ack settles and fails contained within them. SwitchPackager channeldb.FwdOperator // ExtractErrorEncrypter is an interface allowing switch to reextract // error encrypters stored in the circuit map on restarts, since they // are not stored directly within the database. ExtractErrorEncrypter ErrorEncrypterExtracter }
Config defines the configuration for the service. ALL elements within the configuration MUST be non-nil for the service to carry out its duties.
type DecodeHopIteratorRequest ¶
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 HopIterator FailCode lnwire.FailCode }
DecodeHopIteratorResponse encapsulates the outcome of a batched sphinx onion processing.
func (*DecodeHopIteratorResponse) Result ¶
func (r *DecodeHopIteratorResponse) Result() (HopIterator, 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.
type ErrorDecrypter ¶
type ErrorDecrypter interface { // DecryptError peels off each layer of onion encryption from the first // hop, to the source of the error. A fully populated // lnwire.FailureMessage is returned along with the source of the // error. DecryptError(lnwire.OpaqueReason) (*ForwardingError, error) }
ErrorDecrypter is an interface that is used to decrypt the onion encrypted failure reason an extra out a well formed 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) // 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.
func NewMockObfuscator ¶
func NewMockObfuscator() ErrorEncrypter
NewMockObfuscator initializes a dummy mockObfuscator used for testing.
type ErrorEncrypterExtracter ¶
type ErrorEncrypterExtracter func(*btcec.PublicKey) (ErrorEncrypter, lnwire.FailCode)
ErrorEncrypterExtracter defines a function signature that extracts an ErrorEncrypter from an sphinx OnionPacket.
type ForwardingError ¶
type ForwardingError struct { // ErrorSource is the public key of the node that sent the error. With // this information, the dispatcher of a payment can modify their set // of candidate routes in response to the type of error extracted. ErrorSource *btcec.PublicKey // ExtraMsg is an additional error message that callers can provide in // order to provide context specific error details. ExtraMsg string lnwire.FailureMessage }
ForwardingError wraps an lnwire.FailureMessage in a struct that also includes the source of the error.
func (*ForwardingError) Error ¶
func (f *ForwardingError) Error() string
Error implements the built-in error interface. We use this method to allow the switch or any callers to insert additional context to the error message returned.
type ForwardingInfo ¶
type ForwardingInfo struct { // Network is the target blockchain network that the HTLC will travel // over next. Network NetworkHop // 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 ForwardingLog ¶
type ForwardingLog interface { // AddForwardingEvents is a method that should write out the set of // forwarding events in a batch to persistent storage. Outside // sub-systems can then query the contents of the log for analysis, // visualizations, etc. AddForwardingEvents([]channeldb.ForwardingEvent) error }
ForwardingLog is an interface that represents a time series database which keep track of all successfully completed payment circuits. Every few seconds, the switch will collate and flush out all the successful payment circuits during the last interval.
type ForwardingPolicy ¶
type ForwardingPolicy struct { // MinHTLC is the smallest HTLC that is to be forwarded. This is // set when a channel is first opened, and will be static for the // lifetime of the channel. MinHTLC lnwire.MilliSatoshi // BaseFee is the base fee, expressed in milli-satoshi that must be // paid for each incoming HTLC. This field, combined with FeeRate is // used to compute the required fee for a given HTLC. BaseFee lnwire.MilliSatoshi // FeeRate is the fee rate, expressed in milli-satoshi that must be // paid for each incoming HTLC. This field combined with BaseFee is // used to compute the required fee for a given HTLC. FeeRate lnwire.MilliSatoshi // TimeLockDelta is the absolute time-lock value, expressed in blocks, // that will be subtracted from an incoming HTLC's timelock value to // create the time-lock value for the forwarded outgoing HTLC. The // following constraint MUST hold for an HTLC to be forwarded: // // * incomingHtlc.timeLock - timeLockDelta = fwdInfo.OutgoingCTLV // // where fwdInfo is the forwarding information extracted from the // per-hop payload of the incoming HTLC's onion packet. TimeLockDelta uint32 }
ForwardingPolicy describes the set of constraints that a given ChannelLink is to adhere to when forwarding HTLC's. For each incoming HTLC, this set of constraints will be consulted in order to ensure that adequate fees are paid, and our time-lock parameters are respected. In the event that an incoming HTLC violates any of these constraints, it is to be _rejected_ with the error possibly carrying along a ChannelUpdate message that includes the latest policy.
type HopIterator ¶
type HopIterator interface { // ForwardingInstructions 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. ForwardingInstructions() ForwardingInfo // 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) }
HopIterator 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 InvoiceDatabase ¶
type InvoiceDatabase interface { // LookupInvoice attempts to look up an invoice according to its 32 // byte payment hash. LookupInvoice(chainhash.Hash) (channeldb.Invoice, error) // SettleInvoice attempts to mark an invoice corresponding to the // passed payment hash as fully settled. SettleInvoice(chainhash.Hash) error }
InvoiceDatabase is an interface which represents the persistent subsystem which may search, lookup and settle invoices.
type Keystone ¶
type Keystone struct { InKey CircuitKey OutKey CircuitKey }
Keystone is a tuple binding an incoming and outgoing CircuitKey. Keystones are preemptively written by an outgoing link before signing a new commitment state, and cements which HTLCs we are awaiting a response from a remote peer.
type MailBox ¶
type MailBox interface { // AddMessage appends a new message to the end of the message queue. AddMessage(msg lnwire.Message) error // AddPacket appends a new message to the end of the packet queue. AddPacket(pkt *htlcPacket) error // HasPacket queries the packets for a circuit key, this is used to drop // packets bound for the switch that already have a queued response. HasPacket(CircuitKey) bool // AckPacket removes a packet from the mailboxes in-memory replay // buffer. This will prevent a packet from being delivered after a link // restarts if the switch has remained online. AckPacket(CircuitKey) error // MessageOutBox returns a channel that any new messages ready for // delivery will be sent on. MessageOutBox() chan lnwire.Message // PacketOutBox returns a channel that any new packets ready for // delivery will be sent on. PacketOutBox() chan *htlcPacket // Clears any pending wire messages from the inbox. ResetMessages() error // Reset the packet head to point at the first element in the list. ResetPackets() error // Start starts the mailbox and any goroutines it needs to operate // properly. Start() error // Stop signals the mailbox and its goroutines for a graceful shutdown. Stop() error }
MailBox is an interface which represents a concurrent-safe, in-order delivery queue for messages from the network and also from the main switch. This struct servers as a buffer between incoming messages, and messages to the handled by the link. Each of the mutating methods within this interface should be implemented in a non-blocking manner.
type NetworkHop ¶
type NetworkHop uint8
NetworkHop 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 ( // BitcoinHop denotes that an HTLC is to be forwarded along the Bitcoin // link with the specified short channel ID. BitcoinHop NetworkHop = iota // LitecoinHop denotes that an HTLC is to be forwarded along the // Litecoin link with the specified short channel ID. LitecoinHop )
func (NetworkHop) String ¶
func (c NetworkHop) String() string
String returns the string representation of the target NetworkHop.
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) (HopIterator, 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) 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 PaymentCircuit ¶
type PaymentCircuit struct { // AddRef is the forward reference of the Add update in the incoming // link's forwarding package. This value is set on the htlcPacket of the // returned settle/fail so that it can be removed from disk. AddRef channeldb.AddRef // Incoming is the circuit key identifying the incoming channel and htlc // index from which this ADD originates. Incoming CircuitKey // Outgoing is the circuit key identifying the outgoing channel, and the // HTLC index that was used to forward the ADD. It will be nil if this // circuit's keystone has not been set. Outgoing *CircuitKey // PaymentHash used as unique identifier of payment. PaymentHash [32]byte // IncomingAmount is the value of the HTLC from the incoming link. IncomingAmount lnwire.MilliSatoshi // OutgoingAmount specifies the value of the HTLC leaving the switch, // either as a payment or forwarded amount. OutgoingAmount lnwire.MilliSatoshi // ErrorEncrypter is used to re-encrypt the onion failure before // sending it back to the originator of the payment. ErrorEncrypter ErrorEncrypter // LoadedFromDisk is set true for any circuits loaded after the circuit // map is reloaded from disk. // // NOTE: This value is determined implicitly during a restart. It is not // persisted, and should never be set outside the circuit map. LoadedFromDisk bool }
PaymentCircuit is used by the switch as placeholder between when the switch makes a forwarding decision and the outgoing link determines the proper HTLC ID for the local log. After the outgoing HTLC ID has been determined, the half circuit will be converted into a full PaymentCircuit.
func (*PaymentCircuit) Decode ¶
func (c *PaymentCircuit) Decode(r io.Reader) error
Decode reads a PaymentCircuit from the provided io.Reader.
func (*PaymentCircuit) Encode ¶
func (c *PaymentCircuit) Encode(w io.Writer) error
Encode writes a PaymentCircuit to the provided io.Writer.
func (*PaymentCircuit) HasKeystone ¶
func (c *PaymentCircuit) HasKeystone() bool
HasKeystone returns true if an outgoing link has assigned this circuit's outgoing circuit key.
func (*PaymentCircuit) InKey ¶
func (c *PaymentCircuit) InKey() CircuitKey
InKey returns the primary identifier for the circuit corresponding to the incoming HTLC.
func (*PaymentCircuit) OutKey ¶
func (c *PaymentCircuit) OutKey() CircuitKey
OutKey returns the keystone identifying the outgoing link and HTLC ID. If the circuit hasn't been completed, this method returns an EmptyKeystone, which is an invalid outgoing circuit key. Only call this method if HasKeystone returns true.
type Peer ¶
type Peer interface { // SendMessage sends message to remote peer. SendMessage(lnwire.Message) error // WipeChannel removes the channel uniquely identified by its channel // point from all indexes associated with the peer. WipeChannel(*wire.OutPoint) error // PubKey returns the serialize public key of the source peer. PubKey() [33]byte // Disconnect disconnects with peer if we have error which we can't // properly handle. Disconnect(reason error) }
Peer is an interface which represents the remote lightning node inside our system.
type Sequencer ¶
type Sequencer interface { // NextID returns a unique sequence number for each invocation. NextID() (uint64, error) }
Sequencer emits sequence numbers for locally initiated HTLCs. These are only used internally for tracking pending payments, however they must be unique in order to avoid circuit key collision in the circuit map.
type SphinxErrorDecrypter ¶
type SphinxErrorDecrypter struct {
*sphinx.OnionErrorDecrypter
}
SphinxErrorDecrypter wraps the sphinx data SphinxErrorDecrypter and maps the returned errors to concrete lnwire.FailureMessage instances.
func (*SphinxErrorDecrypter) DecryptError ¶
func (s *SphinxErrorDecrypter) DecryptError(reason lnwire.OpaqueReason) (*ForwardingError, error)
DecryptError peels off each layer of onion encryption from the first hop, to the source of the error. A fully populated lnwire.FailureMessage is returned along with the source of the error.
NOTE: Part of the ErrorDecrypter interface.
type SphinxErrorEncrypter ¶
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) 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.
type Switch ¶
type Switch struct {
// contains filtered or unexported fields
}
Switch is the central messaging bus for all incoming/outgoing HTLCs. Connected peers with active channels are treated as named interfaces which refer to active channels as links. A link is the switch's message communication point with the goroutine that manages an active channel. New links are registered each time a channel is created, and unregistered once the channel is closed. The switch manages the hand-off process for multi-hop HTLCs, forwarding HTLCs initiated from within the daemon, and finally notifies users local-systems concerning their outstanding payment requests.
func (*Switch) AddLink ¶
func (s *Switch) AddLink(link ChannelLink) error
AddLink is used to initiate the handling of the add link command. The request will be propagated and handled in the main goroutine.
func (*Switch) CircuitModifier ¶
func (s *Switch) CircuitModifier() CircuitModifier
CircuitModifier returns a reference to subset of the interfaces provided by the circuit map, to allow links to open and close circuits.
func (*Switch) CloseLink ¶
func (s *Switch) CloseLink(chanPoint *wire.OutPoint, closeType ChannelCloseType, targetFeePerKw lnwallet.SatPerKWeight) (chan *lnrpc.CloseStatusUpdate, chan error)
CloseLink creates and sends the close channel command to the target link directing the specified closure type. If the closure type if CloseRegular, then the last parameter should be the ideal fee-per-kw that will be used as a starting point for close negotiation.
func (*Switch) FlushForwardingEvents ¶
FlushForwardingEvents flushes out the set of pending forwarding events to the persistent log. This will be used by the switch to periodically flush out the set of forwarding events to disk. External callers can also use this method to ensure all data is flushed to dis before querying the log.
func (*Switch) ForwardPackets ¶
ForwardPackets adds a list of packets to the switch for processing. Fails and settles are added on a first past, simultaneously constructing circuits for any adds. After persisting the circuits, another pass of the adds is given to forward them through the router.
NOTE: This method guarantees that the returned err chan will eventually be closed. The receiver should read on the channel until receiving such a signal.
func (*Switch) GetLink ¶
func (s *Switch) GetLink(chanID lnwire.ChannelID) (ChannelLink, error)
GetLink is used to initiate the handling of the get link command. The request will be propagated/handled to/in the main goroutine.
func (*Switch) GetLinksByInterface ¶
func (s *Switch) GetLinksByInterface(hop [33]byte) ([]ChannelLink, error)
GetLinksByInterface fetches all the links connected to a particular node identified by the serialized compressed form of its public key.
func (*Switch) ProcessContractResolution ¶
func (s *Switch) ProcessContractResolution(msg contractcourt.ResolutionMsg) error
ProcessContractResolution is called by active contract resolvers once a contract they are watching over has been fully resolved. The message carries an external signal that *would* have been sent if the outgoing channel didn't need to go to the chain in order to fulfill a contract. We'll process this message just as if it came from an active outgoing channel.
func (*Switch) RemoveLink ¶
RemoveLink is used to initiate the handling of the remove link command. The request will be propagated/handled to/in the main goroutine.
func (*Switch) SendHTLC ¶
func (s *Switch) SendHTLC(nextNode [33]byte, htlc *lnwire.UpdateAddHTLC, deobfuscator ErrorDecrypter) ([sha256.Size]byte, error)
SendHTLC is used by other subsystems which aren't belong to htlc switch package in order to send the htlc update.
func (*Switch) Stop ¶
Stop gracefully stops all active helper goroutines, then waits until they've exited.
func (*Switch) UpdateForwardingPolicies ¶
func (s *Switch) UpdateForwardingPolicies(newPolicy ForwardingPolicy, targetChans ...wire.OutPoint) error
UpdateForwardingPolicies sends a message to the switch to update the forwarding policies for the set of target channels. If the set of targeted channels is nil, then the forwarding policies for all active channels with be updated.
NOTE: This function is synchronous and will block until either the forwarding policies for all links have been updated, or the switch shuts down.
func (*Switch) UpdateShortChanID ¶
func (s *Switch) UpdateShortChanID(chanID lnwire.ChannelID, shortChanID lnwire.ShortChannelID) error
UpdateShortChanID updates the short chan ID for an existing channel. This is required in the case of a re-org and re-confirmation or a channel, or in the case that a link was added to the switch before its short chan ID was known.
type Ticker ¶
Ticker is an interface used to wrap a time.Ticker in a struct, making mocking it easier.
type UnknownEncrypterType ¶
type UnknownEncrypterType EncrypterType
UnknownEncrypterType is an error message used to signal that an unexpected EncrypterType was encountered during decoding.
func (UnknownEncrypterType) Error ¶
func (e UnknownEncrypterType) Error() string
Error returns a formatted error indicating the invalid EncrypterType.