lnd/chanacceptor/interface.go
eugene 1aa9626606
server+funding: allow scid-alias, zero-conf chantypes, scid-alias
feature-bit channels

This allows opening zero-conf chan-type, scid-alias chan-type, and
scid-alias feature-bit channels. scid-alias chan-type channels are
required to be private. Two paths are available for opening a zero-conf
channel:

* explicit chan-type negotiation
* LDK carve-out where chan-types are not used, LND is on the
  receiving end, and a ChannelAcceptor is used to enable zero-conf

When a zero-conf channel is negotiated, the funding manager:
* sends a FundingLocked with an alias
* waits for a FundingLocked from the remote peer
* calls addToRouterGraph to persist the channel using our alias in
  the graph. The peer's alias is used to send them a ChannelUpdate.
* wait for six confirmations. If public, the alias edge in the
  graph is deleted and replaced (not atomically) with the confirmed
  edge. Our policy is also read-and-replaced, but the counterparty's
  policy won't exist until they send it to us.

When a scid-alias-feature channel is negotiated, the funding manager:
* sends a FundingLocked with an alias:
* calls addToRouterGraph, sends ChannelUpdate with the confirmed SCID
  since it exists.
* when six confirmations occurs, the edge is deleted and re-inserted
  since the peer may have sent us an alias ChannelUpdate that we are
  storing in the graph.

Since it is possible for a user to toggle the scid-alias-feature-bit
to on while channels exist in the funding manager, care has been taken
to ensure that an alias is ALWAYS sent in the funding_locked message
if this happens.
2022-07-07 17:10:28 -04:00

121 lines
3.8 KiB
Go

package chanacceptor
import (
"errors"
"github.com/btcsuite/btcd/btcec/v2"
"github.com/btcsuite/btcd/btcutil"
"github.com/lightningnetwork/lnd/lnwire"
)
var (
// errChannelRejected is returned when the rpc channel acceptor rejects
// a channel due to acceptor timeout, shutdown, or because no custom
// error value is available when the channel was rejected.
errChannelRejected = errors.New("channel rejected")
)
// ChannelAcceptRequest is a struct containing the requesting node's public key
// along with the lnwire.OpenChannel message that they sent when requesting an
// inbound channel. This information is provided to each acceptor so that they
// can each leverage their own decision-making with this information.
type ChannelAcceptRequest struct {
// Node is the public key of the node requesting to open a channel.
Node *btcec.PublicKey
// OpenChanMsg is the actual OpenChannel protocol message that the peer
// sent to us.
OpenChanMsg *lnwire.OpenChannel
}
// ChannelAcceptResponse is a struct containing the response to a request to
// open an inbound channel. Note that fields added to this struct must be added
// to the mergeResponse function to allow combining of responses from different
// acceptors.
type ChannelAcceptResponse struct {
// ChanAcceptError the error returned by the channel acceptor. If the
// channel was accepted, this value will be nil.
ChanAcceptError
// UpfrontShutdown is the address that we will set as our upfront
// shutdown address.
UpfrontShutdown lnwire.DeliveryAddress
// CSVDelay is the csv delay we require for the remote peer.
CSVDelay uint16
// Reserve is the amount that require the remote peer hold in reserve
// on the channel.
Reserve btcutil.Amount
// InFlightTotal is the maximum amount that we allow the remote peer to
// hold in outstanding htlcs.
InFlightTotal lnwire.MilliSatoshi
// HtlcLimit is the maximum number of htlcs that we allow the remote
// peer to offer us.
HtlcLimit uint16
// MinHtlcIn is the minimum incoming htlc value allowed on the channel.
MinHtlcIn lnwire.MilliSatoshi
// MinAcceptDepth is the minimum depth that the initiator of the
// channel should wait before considering the channel open.
MinAcceptDepth uint16
// ZeroConf indicates that the fundee wishes to send min_depth = 0 and
// request a zero-conf channel with the counter-party.
ZeroConf bool
}
// NewChannelAcceptResponse is a constructor for a channel accept response,
// which creates a response with an appropriately wrapped error (in the case of
// a rejection) so that the error will be whitelisted and delivered to the
// initiating peer. Accepted channels simply return a response containing a nil
// error.
func NewChannelAcceptResponse(accept bool, acceptErr error,
upfrontShutdown lnwire.DeliveryAddress, csvDelay, htlcLimit,
minDepth uint16, reserve btcutil.Amount, inFlight,
minHtlcIn lnwire.MilliSatoshi, zeroConf bool) *ChannelAcceptResponse {
resp := &ChannelAcceptResponse{
UpfrontShutdown: upfrontShutdown,
CSVDelay: csvDelay,
Reserve: reserve,
InFlightTotal: inFlight,
HtlcLimit: htlcLimit,
MinHtlcIn: minHtlcIn,
MinAcceptDepth: minDepth,
ZeroConf: zeroConf,
}
// If we want to accept the channel, we return a response with a nil
// error.
if accept {
return resp
}
// Use a generic error when no custom error is provided.
if acceptErr == nil {
acceptErr = errChannelRejected
}
resp.ChanAcceptError = ChanAcceptError{
error: acceptErr,
}
return resp
}
// RejectChannel returns a boolean that indicates whether we should reject the
// channel.
func (c *ChannelAcceptResponse) RejectChannel() bool {
return c.error != nil
}
// ChannelAcceptor is an interface that represents a predicate on the data
// contained in ChannelAcceptRequest.
type ChannelAcceptor interface {
Accept(req *ChannelAcceptRequest) *ChannelAcceptResponse
}