Skip to content

routing: add custom sender-sider bandwidth hint selection as a top level config option  #8617

@Roasbeef

Description

@Roasbeef

For certain custom channel types, we'll wan to extend the default bandwidthHints that the router uses to introspect into the local balance of a channel to make decisions w.r.t which channel should be selected as an outgoing edge. As an example, given a TLV blob contained in an update_add_htlc message, and a custom blob that may be stored along side an OpenChannel/ChannleCommitment struct, even though channels ${X, Y, Z}$ may have enough bandwidth to satisfy a payment of amount $M$, we may actually want to take channel $A$ instead, as $F(htlc, A) == true$.

In this case, we want the creator of a new lnd process in an existing go program to be able to provide the function $F$ to us.

When we decide to make a payment, we'll make the following series of calls:

  • We'll call getOutgoingBalance to see if any of our local channels can even carry the payment: https://github.com/lightningnetwork/lnd/blob/master/routing/pathfind.go#L602
  • That in turn will call getBalance to see if the link can actually forward, and if so, return the active balance: https://github.com/lightningnetwork/lnd/blob/master/routing/bandwidth.go#L10-L22
    • This is the first instance that we'll want our cut out to apply. First, we'll need to extend getBandwidth to optionally be aware of the TLV blob of a given HTLC. Then, we'll want to just return zero (similar to if !link.EligibleToForward()), if our function $F$ returns false.
  • Finally once we decide that some of our channels can carry the HTLC, we'll call getEdgeLocal:
    func (u *edgeUnifier) getEdgeLocal(netAmtReceived lnwire.MilliSatoshi,
    .
    • This is the second instance where our cut out will apply. Unconditionally, if $F$ returns true for a channel, we want to return the bandwidth. Otherwise, skip it if $F$ is present (could be fn.Option), but returns false.

Here's an interface sketch that may be useful:

type TlvTrafficShaper interface {
    ShouldCarryPayment(amt lnwire.Millisatoshi, htlcTLV, channelBlob tlv.Blob) bool
}

The htlcTLV will just be what's present in the update_add_htlc, tho we'll also need a way to pass in a custom instance as path finding hasn't completed yet. channelBlob will be available based on the channels in the link.

Metadata

Metadata

Assignees

Labels

advancedIssues suitable for very experienced developersconfigParameters/arguments/config file related issues/PRsenhancementImprovements to existing features / behaviourrefactoringrouting

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions