2019-08-07 22:15:14 -04:00
|
|
|
package chanacceptor
|
|
|
|
|
|
|
|
import (
|
2020-11-09 09:34:50 +02:00
|
|
|
"errors"
|
|
|
|
|
2022-02-23 14:48:00 +01:00
|
|
|
"github.com/btcsuite/btcd/btcec/v2"
|
|
|
|
"github.com/btcsuite/btcd/btcutil"
|
2019-08-07 22:15:14 -04:00
|
|
|
"github.com/lightningnetwork/lnd/lnwire"
|
|
|
|
)
|
|
|
|
|
2020-11-09 09:34:50 +02:00
|
|
|
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")
|
|
|
|
)
|
|
|
|
|
2019-08-07 22:15:14 -04:00
|
|
|
// 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
|
|
|
|
}
|
|
|
|
|
2020-11-09 09:34:50 +02:00
|
|
|
// ChannelAcceptResponse is a struct containing the response to a request to
|
2020-11-09 09:34:52 +02:00
|
|
|
// 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.
|
2020-11-09 09:34:50 +02:00
|
|
|
type ChannelAcceptResponse struct {
|
|
|
|
// ChanAcceptError the error returned by the channel acceptor. If the
|
|
|
|
// channel was accepted, this value will be nil.
|
|
|
|
ChanAcceptError
|
2020-11-09 09:34:52 +02:00
|
|
|
|
|
|
|
// 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
|
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-04-04 16:47:05 -04:00
|
|
|
|
|
|
|
// ZeroConf indicates that the fundee wishes to send min_depth = 0 and
|
|
|
|
// request a zero-conf channel with the counter-party.
|
|
|
|
ZeroConf bool
|
2020-11-09 09:34:50 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
// 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.
|
2020-11-09 09:34:52 +02:00
|
|
|
func NewChannelAcceptResponse(accept bool, acceptErr error,
|
|
|
|
upfrontShutdown lnwire.DeliveryAddress, csvDelay, htlcLimit,
|
|
|
|
minDepth uint16, reserve btcutil.Amount, inFlight,
|
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-04-04 16:47:05 -04:00
|
|
|
minHtlcIn lnwire.MilliSatoshi, zeroConf bool) *ChannelAcceptResponse {
|
2020-11-09 09:34:52 +02:00
|
|
|
|
|
|
|
resp := &ChannelAcceptResponse{
|
|
|
|
UpfrontShutdown: upfrontShutdown,
|
|
|
|
CSVDelay: csvDelay,
|
|
|
|
Reserve: reserve,
|
|
|
|
InFlightTotal: inFlight,
|
|
|
|
HtlcLimit: htlcLimit,
|
|
|
|
MinHtlcIn: minHtlcIn,
|
|
|
|
MinAcceptDepth: minDepth,
|
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-04-04 16:47:05 -04:00
|
|
|
ZeroConf: zeroConf,
|
2020-11-09 09:34:52 +02:00
|
|
|
}
|
2020-11-09 09:34:50 +02:00
|
|
|
|
|
|
|
// If we want to accept the channel, we return a response with a nil
|
|
|
|
// error.
|
|
|
|
if accept {
|
2020-11-09 09:34:52 +02:00
|
|
|
return resp
|
2020-11-09 09:34:50 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
// Use a generic error when no custom error is provided.
|
|
|
|
if acceptErr == nil {
|
|
|
|
acceptErr = errChannelRejected
|
|
|
|
}
|
|
|
|
|
2020-11-09 09:34:52 +02:00
|
|
|
resp.ChanAcceptError = ChanAcceptError{
|
|
|
|
error: acceptErr,
|
2020-11-09 09:34:50 +02:00
|
|
|
}
|
2020-11-09 09:34:52 +02:00
|
|
|
|
|
|
|
return resp
|
2020-11-09 09:34:50 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
// 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
|
2019-08-07 22:15:14 -04:00
|
|
|
// contained in ChannelAcceptRequest.
|
|
|
|
type ChannelAcceptor interface {
|
2020-11-09 09:34:50 +02:00
|
|
|
Accept(req *ChannelAcceptRequest) *ChannelAcceptResponse
|
2019-08-07 22:15:14 -04:00
|
|
|
}
|
2022-07-08 17:18:14 -04:00
|
|
|
|
|
|
|
// MultiplexAcceptor is an interface that abstracts the ability of a
|
|
|
|
// ChannelAcceptor to contain sub-ChannelAcceptors.
|
|
|
|
type MultiplexAcceptor interface {
|
|
|
|
// Embed the ChannelAcceptor.
|
|
|
|
ChannelAcceptor
|
|
|
|
|
|
|
|
// AddAcceptor nests a ChannelAcceptor inside the MultiplexAcceptor.
|
|
|
|
AddAcceptor(acceptor ChannelAcceptor) uint64
|
|
|
|
|
|
|
|
// Remove a sub-ChannelAcceptor.
|
|
|
|
RemoveAcceptor(id uint64)
|
|
|
|
}
|