lnmux

package module
v1.0.0 Latest Latest
Warning

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

Go to latest
Published: Jan 26, 2023 License: MIT Imports: 37 Imported by: 0

README

Lightning Multiplexer

This repository contains the code for the lnmux service. The problem that lnmux solves is fail-over for incoming Lightning payments. BOLT11 invoices are bound to a single node. If that node goes down, the invoice is no longer payable. The same is true for the node or its peers running out of inbound liquidity.

What lnmux allows you to do is set up a cluster of nodes where each of these nodes can settle any invoice. If a node is unable to accept payments for one of the reasons above, senders will still be able to pay the invoice via one of the other nodes.

Even with all nodes in the cluster available, it can be advantageous for the sender to have multiple routing options to better utilize liquidity and minimise fees. If needed, multi-part payments can be completed through more than one cluster node.

Running

For the setup, it is assumed that there are multiple LND nodes running with connections to the wider Lightning network and sufficient inbound liquidity. The minimally required version of lnd is v0.15.0-beta.

  • Run the lnd nodes with the --requireinterceptor option. This ensures that HTLCs are always offered to interceptor applications eventually, even when there are momentary disconnects. Not running with this option can lead to HTLCs failing after the invoice that they pay to has been marked as settled.

  • Create a postgres database. Note that lnmux uses stateless invoices. This means that the database only contains settled invoices.

  • Create a config file for lnmuxd named lnmux.yml. An example can be found in this repository. The config file contains the following elements:

    • LND nodes configuration: TLS certificate, macaroon, address and pubkey. Pubkey is configured as a protection against unintentionally connecting to the wrong node.
    • Postgres connection string for the database created above (can be overridden by the environment variable LNMUX_PERSISTENCE_POSTGRES_DSN to avoid exposing credentials).
    • 32-byte Identity PRIVATE key. This key is used to generate invoices and decode incoming htlcs. In a production environment, this key must be protected carefully (can be overridden by the environment variable LNMUX_IDENTITY_KEY to avoid exposing the private key).
    • Your logging configuration. The most important options are the logs level, the encoding format and the activation of grpc logs.
  • Initialize the database: go run ./cmd/lnmuxd -c lnmux.yml migrate init

  • Migrate the database to the latest version: go run ./cmd/lnmuxd -c lnmux.yml migrate up

  • Run lnmuxd: go run ./cmd/lnmuxd -c lnmux.yml run. This opens connections to all LND nodes via the HTLC interceptor API. Incoming htlcs are collected and assembled into sets. When a set is complete, an external application connected to lnmux decides whether to settle the invoice. If the application sends a settle request, the invoice is marked as settled in the lnmux database and a settle action is returned to the LND instance(s) holding the HTLC(s).

  • Invoice generation is taken over by lnmuxd. It is no longer a responsibility of the LND nodes. To generate an invoice, run:

    grpcurl -plaintext -v \
    -d '{"amt_msat":20000, "expiry_secs":600}' \
    localhost:9190 lnmux.Service.AddInvoice`.
    

    If you decode the invoice, you'll find route hints from each node in the cluster to the lnmuxd public key. lnmuxd acts as a virtual node without real channels.

    The invoice is not stored in the lnmux database and does not take up any disk space. This makes lnmux particularly suitable for scenarios where large numbers of invoices are generated.

    Below is an example invoice generated by lnmuxd.

    {
        "destination": "03422175ba6fed348de4f273cf81627c26d5ab2a78bfdc1a39e6f9c06354dd9371",
        "payment_hash": "fd3b0f9a077006697ba8f82cc5673d1511cb11d1d1012662bf0c0b3c93f4245e",
        ...
        "route_hints": [
            {
                "hop_hints": [
                    {
                        "node_id": "020723c6f2203f1072336bd0e71bf4d11e367ab0b3010ce60c080abef0d4770db8",
                        "chan_id": "12345",
                        "fee_base_msat": 0,
                        "fee_proportional_millionths": 0,
                        "cltv_expiry_delta": 40
                    }
                ]
            },
            {
                "hop_hints": [
                    {
                        "node_id": "026ff75cb2ff49b864833aa3c93970069070231a9ad64819252e190406dd0a6976",
                        "chan_id": "12345",
                        "fee_base_msat": 0,
                        "fee_proportional_millionths": 0,
                        "cltv_expiry_delta": 40
                    }
                ]
            }
        ],
        "payment_addr": "8f135e331fed1858e467f775fa644751a2b0da17ee0676ebb1bc8a994d667be6",
        "num_msat": "6000",
        "features": {
            ...
        }
    }
    
  • It should be possible to pay this invoice as long as at least one node in the cluster is available.

  • When the payment comes in, an event is generated. Events can be listened for via:

    grpcurl -plaintext -v localhost:9190 lnmux.Service.SubscribeInvoiceAccepted
    

    Each time an invoice is accepted, you will receive a pair (hash , setID):

    Response contents:
    {
      "hash": "rCdcdDvpo7oqkO1Gkh1hikofseQpUZhgAIaw6gYXz7M=",
      "setId": "J1q7YDvixChKrJjjP/yvv16KiQdpHqwW7gy8jqxDAvI="
    }
    
  • To request settlement of the invoice, invoke:

    grpcurl -plaintext -v \
    -d '{"hash":"rCdcdDvpo7oqkO1Gkh1hikofseQpUZhgAIaw6gYXz7M=","set_id":"J1q7YDvixChKrJjjP/yvv16KiQdpHqwW7gy8jqxDAvI="}' \
    localhost:9190 lnmux.Service.SettleInvoice`
    

Expected output

If you've set up lnmuxd correctly, output similar to what is shown below is expected.

  • Interception is started on all of your nodes
  • When an HTLC comes in, it is matched against the invoice database. If there is a match, the invoice is loaded into memory.
  • The total amount of the HTLC set is tracked. When the total amount matches the invoice amount, HTLC settle resolutions are sent to LND.
2022-04-19T08:39:09.333+0200	INFO	Succesfully connected to LND	{"node": "020723c6f2203f1072336bd0e71bf4d11e367ab0b3010ce60c080abef0d4770db8"}
2022-04-19T08:39:09.339+0200	INFO	Succesfully connected to LND	{"node": "026ff75cb2ff49b864833aa3c93970069070231a9ad64819252e190406dd0a6976"}
2022-04-19T08:39:09.347+0200	INFO	InvoiceRegistry starting
2022-04-19T08:39:09.347+0200	INFO	Press ctrl-c to exit
2022-04-19T08:39:09.347+0200	DEBUG	Starting htlc interception	{"node": "026ff75cb2ff49b864833aa3c93970069070231a9ad64819252e190406dd0a6976"}
2022-04-19T08:39:09.347+0200	DEBUG	Starting htlc interception	{"node": "020723c6f2203f1072336bd0e71bf4d11e367ab0b3010ce60c080abef0d4770db8"}
2022-04-19T08:39:09.347+0200	DEBUG	Starting main event loop
2022-04-19T08:39:23.166+0200	INFO	Htlc received	{"hash": "fd3b0f9a077006697ba8f82cc5673d1511cb11d1d1012662bf0c0b3c93f4245e", "source": "026ff75cb2ff49b864833aa3c93970069070231a9ad64819252e190406dd0a6976", "circuitKey": "1161084279062528:7"}
2022-04-19T08:39:23.224+0200	DEBUG	Loaded invoice from db	{"hash": "fd3b0f9a077006697ba8f82cc5673d1511cb11d1d1012662bf0c0b3c93f4245e"}
2022-04-19T08:39:23.225+0200	DEBUG	Hodl subscribe for 1161084279062528:7
2022-04-19T08:39:23.225+0200	DEBUG	Htlc accepted: hash=fd3b0f9a077006697ba8f82cc5673d1511cb11d1d1012662bf0c0b3c93f4245e, amt=6000 mSAT, expiry=1110, circuit=1161084279062528:7, mpp=total=6000 mSAT, addr=8f135e331fed1858e467f775fa644751a2b0da17ee0676ebb1bc8a994d667be6
2022-04-19T08:39:23.237+0200	DEBUG	Sending settle resolution	{"hash": "fd3b0f9a077006697ba8f82cc5673d1511cb11d1d1012662bf0c0b3c93f4245e", "source": "026ff75cb2ff49b864833aa3c93970069070231a9ad64819252e190406dd0a6976", "circuitKey": "1161084279062528:7", "outcome": "settled"}

Leader election

Lnmux is designed as a single-instance process. Running multiple instances connected to the same database simultaneously results in incorrect behavior and may put funds at risk.

To ensure that there can only ever be one instance running, k8s leader election can be enabled via the DistributedLock config group.

Invoice lifecycle

Note that only the states accepted, settle requested and settled are published to callers of the SubscribeSingleInvoice rpc. Lnmux isn't aware of open invoices because it is stateless.

The transition from settle requested to settled can be made more robust in the future. This transition is happening already, but not backed by an actual final settle event from lnd. See https://github.com/lightningnetwork/lnd/issues/6208.

Docker Instructions

We provide a Dockerfile to launch lnmux using docker.

This Dockerfile will build 2 different images: one for debian and the other one for alpine.

You have 2 options to get the lnmux image:

  • Either, building it by yourself: navigate to the lnmux repository and simply do:

    docker build -t lnmux .
    
  • Or pull directly the image we pushed into ghcr.io (You can check existing images here)

       docker pull ghcr.io/bottlepay/lnmux:{tag|sha}
    

However, we don't provide any configuration file in the Dockerfile (and don't do the migration either). You need to provide certificates (TLS/Macaroon) as well to connect lnd nodes.

To do so, you can simply use --mount:

 docker run -it \
  --mount type=bind,source="$(pwd)/lnmux.yml",target=/app/lnmux.yml \
  --mount type=bind,source="$(pwd)/lnd/certs",target=/app/certs  \
  ghcr.io/bottlepay/lnmux:sha-bf41263-alpine /bin/sh -c \
  "/usr/bin/lnmuxd -c /app/lnmux.yml migrate init && \
   /usr/bin/lnmuxd -c /app/lnmux.yml migrate up && \
   /usr/bin/lnmuxd -c /app/lnmux.yml run"

⚠️ Don't forget to add before starting nodes connected to lnmux (aka Alice and Bob):

  • --requireinterceptor to make sure all htlcs are intercepted
  • --tlsextradomain=host.docker.internal to add docker DSN to TLS certs (otherwise you can't connect from a docker container)

If your nodes are already started, you will have to stop them, remove manually tls certs and then restart them.

Furthermore, you must use host.docker.internal instead of localhost in your configuration (plus --add-host host.docker.internal:host-gateway for Linux users).

Regtest testing

The minimal setup to test on regtest is to create three LND nodes Alice, Bob and Carol. Alice and Bob should have a channel with Carol, and lnmuxd should be connected to Alice and Bob.

The typical workflow is:

  • Create invoices using lnmux
  • Carol pays the invoices
  • lnmux generates accepted events and settles the invoices either through Alice or Bob.

Experimental

This software is in an experimental state. At this stage, breaking changes can happen and may not always include a database migration. Use at your own risk.

Documentation

Index

Constants

View Source
const DefaultGracePeriodWithoutSubscribers = 30 * time.Second

DefaultGracePeriodWithoutSubscribers is the default period during which the subscriberManager is waiting for a subscriber to reconnect.

View Source
const (
	// DefaultHtlcHoldDuration defines the default for how long mpp htlcs
	// are held while waiting for the other set members to arrive.
	DefaultHtlcHoldDuration = 120 * time.Second
)

Variables

View Source
var (
	// ErrInvoiceAlreadyCanceled is returned when the invoice is already
	// canceled.
	ErrInvoiceAlreadyCanceled = errors.New("invoice already canceled")

	// ErrInvoiceCannotOpen is returned when an attempt is made to move an
	// invoice to the open state.
	ErrInvoiceCannotOpen = errors.New("cannot move invoice to open")

	// ErrInvoiceCannotAccept is returned when an attempt is made to accept
	// an invoice while the invoice is not in the open state.
	ErrInvoiceCannotAccept = errors.New("cannot accept invoice")

	// ErrInvoicePreimageMismatch is returned when the preimage doesn't
	// match the invoice hash.
	ErrInvoicePreimageMismatch = errors.New("preimage does not match")

	// ErrEmptyHTLCSet is returned when attempting to accept or settle and
	// HTLC set that has no HTLCs.
	ErrEmptyHTLCSet = errors.New("cannot settle/accept empty HTLC set")
)
View Source
var (
	// ErrInvoiceExpiryTooSoon is returned when an invoice is attempted to be
	// accepted or settled with not enough blocks remaining.
	ErrInvoiceExpiryTooSoon = errors.New("invoice expiry too soon")

	// ErrInvoiceAmountTooLow is returned  when an invoice is attempted to be
	// accepted or settled with an amount that is too low.
	ErrInvoiceAmountTooLow = errors.New("paid amount less than invoice amount")

	// ErrShuttingDown is returned when an operation failed because the
	// invoice registry is shutting down.
	ErrShuttingDown = errors.New("invoice registry shutting down")

	// ErrAutoSettling is returned when a settle request is made in
	// auto-settle mode.
	ErrAutoSettling = errors.New("lnmux is in auto-settle mode")

	ErrSettleRequested = errors.New("invoice settle already requested")
)

Functions

This section is empty.

Types

type AcceptCallback

type AcceptCallback func(lntypes.Hash, SetID)

type FailResolutionResult

type FailResolutionResult uint8

FailResolutionResult provides metadata about a htlc that was failed by the registry. It can be used to take custom actions on resolution of the htlc.

const (

	// ResultExpiryTooSoon is returned when we do not accept an invoice
	// payment because it expires too soon.
	ResultExpiryTooSoon FailResolutionResult

	// ResultInvoiceNotOpen is returned when a mpp invoice is not open.
	ResultInvoiceNotOpen

	// ResultMppTimeout is returned when an invoice paid with multiple
	// partial payments times out before it is fully paid.
	ResultMppTimeout

	// ResultAddressMismatch is returned when the payment address for a mpp
	// invoice does not match.
	ResultAddressMismatch

	// ResultHtlcSetTotalMismatch is returned when the amount paid by a
	// htlc does not match its set total.
	ResultHtlcSetTotalMismatch

	// ResultHtlcSetTotalTooLow is returned when a mpp set total is too low
	// for an invoice.
	ResultHtlcSetTotalTooLow

	// ResultHtlcSetOverpayment is returned when a mpp set is overpaid.
	ResultHtlcSetOverpayment

	// ResultInvoiceNotFound is returned when an attempt is made to pay an
	// invoice that is unknown to us.
	ResultInvoiceNotFound

	// ResultHtlcInvoiceTypeMismatch is returned when an AMP HTLC targets a
	// non-AMP invoice and vice versa.
	ResultHtlcInvoiceTypeMismatch

	// ResultCannotSettle is returned when the invoice cannot be settled in
	// the database.
	ResultCannotSettle

	// ResultInvoiceExpired is returned when an invoice has expired.
	ResultInvoiceExpired

	// ResultNoAcceptSubscriber is returned when an htlc is failed because there
	// is no application subscribed to accept events.
	ResultNoAcceptSubscriber

	// ResultAcceptTimeout is returned when the accept timeout is reached
	// without settlement after an invoice is accepted.
	ResultAcceptTimeout
)

func (FailResolutionResult) FailureString

func (f FailResolutionResult) FailureString() string

FailureString returns a string representation of the result.

Note: it is part of the FailureDetail interface.

func (FailResolutionResult) String

func (f FailResolutionResult) String() string

String returns a string representation of the result.

type HtlcFailResolution

type HtlcFailResolution struct {
	// Outcome indicates the outcome of the invoice registry update.
	Outcome FailResolutionResult
}

HtlcFailResolution is an implementation of the HtlcResolution interface which is returned when a htlc is failed.

func NewFailResolution

func NewFailResolution(outcome FailResolutionResult) *HtlcFailResolution

NewFailResolution returns a htlc failure resolution.

type HtlcResolution

type HtlcResolution interface {
}

HtlcResolution describes how an htlc should be resolved.

type HtlcSettleResolution

type HtlcSettleResolution struct {
	// Preimage is the htlc preimage. Its value is nil in case of a cancel.
	Preimage lntypes.Preimage

	// Outcome indicates the outcome of the invoice registry update.
	Outcome SettleResolutionResult
}

HtlcSettleResolution is an implementation of the HtlcResolution interface which is returned when a htlc is settled.

func NewSettleResolution

func NewSettleResolution(preimage lntypes.Preimage,
	outcome SettleResolutionResult) *HtlcSettleResolution

NewSettleResolution returns a htlc resolution which is associated with a settle.

type Invoice

type Invoice struct {
	types.InvoiceCreationData

	Settled bool

	// SettleDate is the exact time the invoice was settled.
	SettleDate time.Time

	// CreationDate is the exact time the invoice was created.
	CreationDate time.Time

	// PaymentRequest is the encoded payment request for this invoice. For
	// spontaneous (keysend) payments, this field will be empty.
	PaymentRequest string
}

Invoice is a payment invoice generated by a payee in order to request payment for some good or service. The inclusion of invoices within Lightning creates a payment work flow for merchants very similar to that of the existing financial system within PayPal, etc. Invoices are added to the database when a payment is requested, then can be settled manually once the payment is received at the upper layer. For record keeping purposes, invoices are never deleted from the database, instead a bit is toggled denoting the invoice has been fully settled. Within the database, all invoices must have a unique payment hash which is generated by taking the sha256 of the payment preimage.

type InvoiceCallback

type InvoiceCallback func(update InvoiceUpdate)

type InvoiceCreator

type InvoiceCreator struct {
	// contains filtered or unexported fields
}

func NewInvoiceCreator

func NewInvoiceCreator(cfg *InvoiceCreatorConfig) (*InvoiceCreator, error)

func (*InvoiceCreator) Create

func (c *InvoiceCreator) Create(amtMSat int64, expiry time.Duration,
	memo string, descHash *lntypes.Hash, cltvDelta uint64) (
	*Invoice, lntypes.Preimage, error)

TODO: Add description hash.

func (*InvoiceCreator) Network

func (c *InvoiceCreator) Network() *chaincfg.Params

func (*InvoiceCreator) NodePubKeys

func (c *InvoiceCreator) NodePubKeys() []*btcec.PublicKey

func (*InvoiceCreator) PubKey

func (c *InvoiceCreator) PubKey() *btcec.PublicKey

type InvoiceCreatorConfig

type InvoiceCreatorConfig struct {
	KeyRing         keychain.SecretKeyRing
	GwPubKeys       []common.PubKey
	ActiveNetParams *chaincfg.Params

	// RoutingPolicy is the policy that is used for the hop hints.
	RoutingPolicy RoutingPolicy
}

type InvoiceRegistry

type InvoiceRegistry struct {
	sync.RWMutex
	// contains filtered or unexported fields
}

InvoiceRegistry is a central registry of all the outstanding invoices created by the daemon. The registry is a thin wrapper around a map in order to ensure that all updates/reads are thread safe.

func NewRegistry

NewRegistry creates a new invoice registry. The invoice registry wraps the persistent on-disk invoice storage with an additional in-memory layer. The in-memory layer is in place such that debug invoices can be added which are volatile yet available system wide within the daemon.

func (*InvoiceRegistry) AutoSettle

func (i *InvoiceRegistry) AutoSettle() bool

func (*InvoiceRegistry) CancelInvoice

func (i *InvoiceRegistry) CancelInvoice(
	hash lntypes.Hash, setID SetID) error

func (*InvoiceRegistry) NotifyExitHopHtlc

func (i *InvoiceRegistry) NotifyExitHopHtlc(h *registryHtlc)

NotifyExitHopHtlc attempts to mark an invoice as settled. The return value describes how the htlc should be resolved.

When the preimage of the invoice is not yet known (hodl invoice), this function moves the invoice to the accepted state. When SettleHoldInvoice is called later, a resolution message will be send back to the caller via the provided hodlChan. Invoice registry sends on this channel what action needs to be taken on the htlc (settle or cancel). The caller needs to ensure that the channel is either buffered or received on from another goroutine to prevent deadlock.

In the case that the htlc is part of a larger set of htlcs that pay to the same invoice (multi-path payment), the htlc is held until the set is complete. If the set doesn't fully arrive in time, a timer will cancel the held htlc.

func (*InvoiceRegistry) RequestSettle

func (i *InvoiceRegistry) RequestSettle(hash lntypes.Hash,
	setID SetID) error

func (*InvoiceRegistry) Run

func (i *InvoiceRegistry) Run(ctx context.Context) error

Start starts the registry and all goroutines it needs to carry out its task.

func (*InvoiceRegistry) SubscribeAccept

func (i *InvoiceRegistry) SubscribeAccept(callback AcceptCallback) (
	func(), error)

type InvoiceUpdate

type InvoiceUpdate struct {
	State persistence.InvoiceState
}

type KeyRing

type KeyRing struct {
	keychain.SecretKeyRing
	// contains filtered or unexported fields
}

KeyRing is an implementation of both the KeyRing and SecretKeyRing interfaces backed by btcwallet's internal root waddrmgr. Internally, we'll be using a ScopedKeyManager to do all of our derivations, using the key scope and scope addr scehma defined above. Re-using the existing key scope construction means that all key derivation will be protected under the root seed of the wallet, making each derived key fully deterministic.

func NewKeyRing

func NewKeyRing(key [32]byte) *KeyRing

NewKeyRing creates a new implementation of the keychain.SecretKeyRing interface backed by btcwallet.

NOTE: The passed waddrmgr.Manager MUST be unlocked in order for the keychain to function.

func (*KeyRing) DeriveKey

func (b *KeyRing) DeriveKey(keyLoc keychain.KeyLocator) (keychain.KeyDescriptor, error)

DeriveKey attempts to derive an arbitrary key specified by the passed KeyLocator. This may be used in several recovery scenarios, or when manually rotating something like our current default node key.

NOTE: This is part of the keychain.KeyRing interface.

func (*KeyRing) DeriveNextKey

func (b *KeyRing) DeriveNextKey(keyFam keychain.KeyFamily) (
	keychain.KeyDescriptor, error)

func (*KeyRing) DerivePrivKey

func (b *KeyRing) DerivePrivKey(keyDesc keychain.KeyDescriptor) (
	*btcec.PrivateKey, error)

DerivePrivKey attempts to derive the private key that corresponds to the passed key descriptor.

NOTE: This is part of the keychain.SecretKeyRing interface.

func (*KeyRing) ECDH

func (b *KeyRing) ECDH(keyDesc keychain.KeyDescriptor,
	pub *btcec.PublicKey) ([32]byte, error)

ECDH performs a scalar multiplication (ECDH-like operation) between the target key descriptor and remote public key. The output returned will be the sha256 of the resulting shared point serialized in compressed format. If k is our private key, and P is the public key, we perform the following operation:

sx := k*P s := sha256(sx.SerializeCompressed())

NOTE: This is part of the keychain.ECDHRing interface.

func (*KeyRing) SignMessage

func (b *KeyRing) SignMessage(keyLoc keychain.KeyLocator,
	msg []byte, doubleHash bool) (*ecdsa.Signature, error)

SignMessage signs the given message, single or double SHA256 hashing it first, with the private key described in the key locator.

NOTE: This is part of the keychain.MessageSignerRing interface.

func (*KeyRing) SignMessageCompact

func (b *KeyRing) SignMessageCompact(keyLoc keychain.KeyLocator,
	msg []byte, doubleHash bool) ([]byte, error)

SignMessageCompact signs the given message, single or double SHA256 hashing it first, with the private key described in the key locator and returns the signature in the compact, public key recoverable format.

NOTE: This is part of the keychain.MessageSignerRing interface.

type Mux

type Mux struct {
	// contains filtered or unexported fields
}

func New

func New(cfg *MuxConfig) (*Mux,
	error)

func (*Mux) ProcessHtlc

func (p *Mux) ProcessHtlc(
	htlc *interceptedHtlc, height int) error

func (*Mux) Run

func (p *Mux) Run(mainCtx context.Context) error

type MuxConfig

type MuxConfig struct {
	KeyRing         keychain.SecretKeyRing
	ActiveNetParams *chaincfg.Params
	SettledHandler  *SettledHandler

	Lnd      lnd.LndClient
	Logger   *zap.SugaredLogger
	Registry *InvoiceRegistry

	// RoutingPolicy is the policy that is enforced for the hop towards the
	// virtual channel.
	RoutingPolicy RoutingPolicy
}

type Payload

type Payload interface {
	// MultiPath returns the record corresponding the option_mpp parsed from
	// the onion payload.
	MultiPath() *record.MPP
}

Payload abstracts access to any additional fields provided in the final hop's TLV onion payload.

type RegistryConfig

type RegistryConfig struct {
	// FinalCltvRejectDelta defines the number of blocks before the expiry
	// of the htlc where we no longer settle it as an exit hop and instead
	// cancel it back. Normally this value should be lower than the cltv
	// expiry of any invoice we create and the code effectuating this should
	// not be hit.
	FinalCltvRejectDelta int32

	// HtlcHoldDuration defines for how long mpp htlcs are held while
	// waiting for the other set members to arrive.
	HtlcHoldDuration time.Duration

	// AcceptTimeout defines for how long a complete htlc set is held before the
	// invoice is cancelled.
	AcceptTimeout time.Duration

	// Clock holds the clock implementation that is used to provide
	// Now() and TickAfter() and is useful to stub out the clock functions
	// during testing.
	Clock clock.Clock

	Logger *zap.SugaredLogger

	// PrivKey is the private key that is used for calculating payment metadata
	// hmacs, which serve as the payment preimage.
	PrivKey [32]byte

	AutoSettle bool

	// GracePeriodWithoutSubscribers is the default period during which the subscriberManager is waiting for a subscriber
	// to reconnect.
	GracePeriodWithoutSubscribers time.Duration
}

RegistryConfig contains the configuration parameters for invoice registry.

type RoutingPolicy

type RoutingPolicy struct {
	CltvDelta   int64
	FeeBaseMsat int64
	FeeRatePpm  int64
}

type SetID

type SetID [32]byte

func (SetID) String

func (s SetID) String() string

type SettleResolutionResult

type SettleResolutionResult uint8

SettleResolutionResult provides metadata which about a htlc that was failed by the registry. It can be used to take custom actions on resolution of the htlc.

const (

	// ResultSettled is returned when we settle an invoice.
	ResultSettled SettleResolutionResult

	// ResultReplayToSettled is returned when we replay a settled invoice.
	ResultReplayToSettled
)

func (SettleResolutionResult) String

func (s SettleResolutionResult) String() string

String returns a string representation of the result.

type SettledHandler

type SettledHandler struct {
	// contains filtered or unexported fields
}

func NewSettledHandler

func NewSettledHandler(cfg *SettledHandlerConfig) *SettledHandler

func (*SettledHandler) WaitForInvoiceSettled

func (p *SettledHandler) WaitForInvoiceSettled(ctx context.Context,
	hash lntypes.Hash) error

type SettledHandlerConfig

type SettledHandlerConfig struct {
	Persister *persistence.PostgresPersister
	Logger    *zap.SugaredLogger
}

Directories

Path Synopsis
cmd
Package lnd is a generated GoMock package.
Package lnd is a generated GoMock package.
lnmuxrpc module

Jump to

Keyboard shortcuts

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